summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdscfg/common
diff options
context:
space:
mode:
authorYuri Pankov <yuri.pankov@nexenta.com>2018-08-07 16:46:21 -0700
committerJoshua M. Clulow <josh@sysmgr.org>2018-08-07 16:46:22 -0700
commitcb41b9c565d4eec9e1f06e24d429696f59f2f07d (patch)
treeee8675f196c2ea84b5ac5c6f0dff8c9e5305f0ee /usr/src/lib/libdscfg/common
parent0e986b9d87352cd82909c748e7f684afe0ed579f (diff)
downloadillumos-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/lib/libdscfg/common')
-rw-r--r--usr/src/lib/libdscfg/common/cfg.c3585
-rw-r--r--usr/src/lib/libdscfg/common/cfg.h180
-rw-r--r--usr/src/lib/libdscfg/common/cfg_cluster.c582
-rw-r--r--usr/src/lib/libdscfg/common/cfg_cluster.h344
-rw-r--r--usr/src/lib/libdscfg/common/cfg_impl.h247
-rw-r--r--usr/src/lib/libdscfg/common/cfg_local.c653
-rw-r--r--usr/src/lib/libdscfg/common/cfg_local.h42
-rw-r--r--usr/src/lib/libdscfg/common/cfg_lockd.h72
-rw-r--r--usr/src/lib/libdscfg/common/cfg_lockdlck.c135
-rw-r--r--usr/src/lib/libdscfg/common/cfg_lockdmsg.c324
-rw-r--r--usr/src/lib/libdscfg/common/cfg_vols.c1286
-rw-r--r--usr/src/lib/libdscfg/common/mapfile-vers100
12 files changed, 0 insertions, 7550 deletions
diff --git a/usr/src/lib/libdscfg/common/cfg.c b/usr/src/lib/libdscfg/common/cfg.c
deleted file mode 100644
index 17f668744a..0000000000
--- a/usr/src/lib/libdscfg/common/cfg.c
+++ /dev/null
@@ -1,3585 +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 <stdio.h>
-#include <sys/mnttab.h>
-#include <sys/vtoc.h>
-#include <errno.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdarg.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/mman.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/stat.h>
-#include <sys/utsname.h>
-
-#include "cfg_impl.h"
-#include "cfg.h"
-#include "cfg_lockd.h"
-
-#if 0
-#define DEBUG_CFGLIST
-#define DEBUG_EXTRA
-#define DEBUG_LIB
-#define DEBUG_NOISY
-#define DEBUG_OUT
-#endif
-
-#define MAX_CFG 16 /* Max. number of lines in /etc/dscfg_format */
-#define MAX_SET 12 /* number of chars in a set name */
-
-
-/* parser tree for config section */
-static struct parser chead[MAX_CFG] = { NULL };
-static int chead_loaded = 0;
-static char config_file[CFG_MAX_BUF];
-static char dectohex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
-#define CHARS_TO_ENCODE "=;\t "
-#define min(a, b) ((a) > (b) ? (b) : (a))
-
-/* field to be sorted on in sorting routines */
-static struct sortby_s {
- char section[CFG_MAX_KEY];
- char field[CFG_MAX_KEY];
- int offset;
- int comperror;
-} sortby;
-
-int cfg_severity = 0;
-char *cfg_perror_str;
-static int cfg_read(cfp_t *);
-static void cfg_read_parser_config(cfp_t *);
-static int cfg_rdlock(CFGFILE *);
-static int cfg_wrlock(CFGFILE *);
-static int cfg_lockd;
-void cfg_replace_lists(cfp_t *);
-void cfg_free_parser_tree();
-void cfg_invalidate_hsizes(int, const char *);
-int cfg_map_cfglists(cfp_t *);
-int cfg_hdrcmp(cfp_t *);
-void cfg_free_cfglist(cfp_t *);
-
-extern cfg_io_t *cfg_block_io_provider(void);
-extern cfg_io_t *cfg_raw_io_provider(void);
-extern int cl_initialized;
-
-#ifdef DEBUG_LIB
-static void
-dump_status(cfp_t *cfp, char *str)
-{
- printf("called from %s\n", str);
- printf(gettext("Header info:\n"
- "\tmagic: %x\tstate: %x\n"),
- cfp->cf_head->h_magic, cfp->cf_head->h_state);
- printf(gettext("Parser section:\n"
- "Start: %x\tsize: %d\toffset: %d\n"),
- cfp->cf_mapped, cfp->cf_head->h_parsesize,
- cfp->cf_head->h_parseoff);
- printf(gettext("Config section:\n"
- "Start: %x\tsize:%d\tacsize: %d\n"),
- cfp->cf_head->h_cparse, cfp->cf_head->h_csize,
- cfp->cf_head->h_acsize);
- printf("\n\tccopy1: %x\tccopy2: %x\n",
- cfp->cf_head->h_ccopy1, cfp->cf_head->h_ccopy2);
- printf(gettext("Sequence:\n"
- "\tseq1: %d\t\tseq2: %d\n"),
- cfp->cf_head->h_seq1, cfp->cf_head->h_seq2);
-}
-#endif /* DEBUG */
-
-/*
- * cfg_get_item
- * return position from parser config given tag and field
- */
-static int
-cfg_get_item(struct parser *tbl, const char *tag, const char *field)
-{
- int i;
- struct lookup *p;
-
- for (i = 0; i < MAX_CFG; i++) {
- /* only as many lists as defined */
- if (tbl[i].tag.l_word[0] == '\0') {
- i = MAX_CFG;
- break;
- }
- if (strcmp(tbl[i].tag.l_word, tag) == 0)
- break;
- }
-
- /* Handle table size */
- if (i < MAX_CFG) {
- p = tbl[i].fld;
- while (p) {
- if (strcmp(p->l_word, field) == 0)
- return (p->l_value);
- p = p->l_next;
- }
- }
-
- /* Handle failure */
- return (-1);
-}
-
-/*
- * cfg_get_num_flds
- * return number of fields for given parser tag
- */
-static int
-cfg_get_num_flds(struct parser *tbl, const char *tag, int *table_index)
-{
- int i;
- int pos = 0;
- struct lookup *p;
-
- for (i = 0; i < MAX_CFG; i++) {
- /* only as many lists as defined */
- if (tbl[i].tag.l_word[0] == '\0') {
- i = MAX_CFG;
- break;
- }
- if (strcmp(tbl[i].tag.l_word, tag) == 0) {
- *table_index = i;
- break;
- }
- }
-
- /* Handle table size */
- if (i < MAX_CFG) {
- p = tbl[i].fld;
- while (p) {
- pos++;
- p = p->l_next;
- }
- return (pos);
- }
-
- return (0);
-}
-
-/*
- * count white space fields
- */
-static int
-cfg_cnt_flds(char *value)
-{
- char *ptr;
- char buf[CFG_MAX_BUF];
- int flds = 0;
-
- if ((value == NULL) || (strlen(value) >= CFG_MAX_BUF))
- return (0);
-
- bzero(buf, CFG_MAX_BUF);
- strcpy(buf, value);
- ptr = strtok(buf, " ");
- while (ptr) {
- flds++;
- ptr = strtok(NULL, " ");
- }
- return (flds);
-}
-
-/*
- * cfg_get_parser_offset
- * returns the index for each
- * section of the parser..
- * ie. parser info for sndr is chead[3].tag.l_word
- * this will help us find sndr quicker, as the
- * the memory picture of the sets mimic this ordering
- */
-static int
-cfg_get_parser_offset(const char *section)
-{
- int i;
-
- for (i = 0; i < MAX_CFG; i++) {
- /* only as many lists as defined */
- if (chead[i].tag.l_word[0] == '\0') {
- i = MAX_CFG;
- break;
- }
- if (strcmp(chead[i].tag.l_word, section) == 0)
- break;
- }
-
- /* Handle table size */
- if (i < MAX_CFG)
- return (i);
-
- /* Handle failure */
- cfg_perror_str = dgettext("cfg",
- "cfg_get_parser_offset: section not found");
- cfg_severity = CFG_EFATAL;
- errno = ESRCH;
- return (-1);
-}
-
-/*
- * cfg_fld_mov
- * move fields from old buffer to new
- * moving only specified fields
- * concates newbuf
- * returns fields moved
- */
-static int
-cfg_fld_mov(char *newbuf, char *oldbuf, int start, int end)
-{
- char buf[CFG_MAX_BUF];
- char *ptr;
- int flds = 0;
-
- bzero(buf, CFG_MAX_BUF);
- if (oldbuf == NULL)
- return (0);
-
- if ((start > end) || (strlen(oldbuf) >= CFG_MAX_BUF)) {
- return (0);
- }
- if (!start || !end)
- return (-1);
- strcpy(buf, oldbuf);
- ptr = strtok(buf, " ");
- while (ptr) {
- flds++;
- if (flds >= start && flds <= end) {
- strcat(newbuf, ptr);
- strcat(newbuf, " ");
- }
- ptr = strtok(NULL, " ");
- }
-
- return (flds);
-}
-
-/*
- * cfg_filter_node
- * return indication if this raw buf should be returned
- * checks cfg->cf_node for filtering
- * We already know that this buf meets most of our criteria
- * find the cnode field in the buf and see if it matches
- * returns
- * TRUE Good entry
- * FALSE Don't use it
- */
-static int
-cfg_filter_node(CFGFILE *cfg, struct parser *tbl, char *buf, char *tag)
-{
- char tmpbuf[CFG_MAX_BUF];
- int i = 1;
- int fld;
- char *ptr;
-
- if (!cfg->cf_node) /* no filter always good */
- return (TRUE);
- bzero(tmpbuf, CFG_MAX_BUF);
- fld = cfg_get_item(tbl, tag, "cnode");
- if (fld < 0) /* no cnode field always good */
- return (TRUE);
- strncpy(tmpbuf, buf, CFG_MAX_BUF);
- if (tmpbuf[CFG_MAX_BUF - 1] != '\0')
- return (FALSE);
- ptr = strtok(tmpbuf, " ");
- while (ptr && (i < fld)) {
- ptr = strtok(NULL, " ");
- i++;
- }
- if (!ptr)
- return (FALSE);
-#ifdef DEBUG_EXTRA
- (void) fprintf(stderr, "cfg_filter_node: node=%s:%d cnode=%s:%d\n",
- cfg->cf_node, strlen(cfg->cf_node), ptr, strlen(ptr));
-#endif
- if (strcmp(ptr, cfg->cf_node) == 0)
- return (TRUE);
- return (FALSE);
-}
-/*
- * cfg_insert_node
- * insert resource in bufs which contain cnode parser field
- */
-static void
-cfg_insert_node(CFGFILE *cfg, struct parser *tbl, char *buf, char *tag)
-{
- char tmpbuf[CFG_MAX_BUF];
- int fld;
- int nflds;
- int table_index;
-
- bzero(tmpbuf, CFG_MAX_BUF);
- strcpy(tmpbuf, " ");
- fld = cfg_get_item(tbl, tag, "cnode");
- nflds = cfg_get_num_flds(tbl, tag, &table_index);
- if ((fld < 0) && !(cfg->cf_node)) /* no cnode field always good */
- return;
-
- cfg_fld_mov(tmpbuf, buf, 1, (fld - 1));
- if (cfg->cf_node)
- strcat(tmpbuf, cfg->cf_node);
- else
- strcat(tmpbuf, "-");
- strcat(tmpbuf, " ");
- cfg_fld_mov(tmpbuf, buf, (fld + 1), nflds);
- bcopy(tmpbuf, buf, strlen(tmpbuf) + 1);
-}
-
-/*
- * cfg_is_cnode
- * Parser current buffer to see if a non-empty " - " cnode exists
- */
-/*ARGSUSED*/
-static int
-cfg_is_cnode(CFGFILE *cfg, struct parser *tbl, char *buf, char *tag)
-{
- char tmpbuf[CFG_MAX_BUF];
- int fld = cfg_get_item(tbl, tag, "cnode");
-
- if (fld >= 0) {
- tmpbuf[0] = '\0';
- cfg_fld_mov(tmpbuf, buf, fld, fld);
- return (strcmp(tmpbuf, "- ") ? TRUE : FALSE);
- }
- return (FALSE);
-}
-/*
- * cfg_get_cstring
- * key determines section and value
- * special considerations:
- * AA.BB.CC...
- * AA = data service tag
- * BB = set number relative to first set (1..n)
- * CC = field of set or if absent, all
- */
-int
-cfg_get_cstring(CFGFILE *cfg, const char *key, void *value, int value_len)
-{
- cfp_t *cfp;
- char buf[CFG_MAX_BUF];
- char tmpkey[CFG_MAX_KEY];
- char *section;
- char set[MAX_SET];
- char *setp;
- char *itemp;
- char *p;
- int pos = 1;
- int setnum;
- int relnum;
- int secnum;
- int numfound;
- int needed;
- int table_offset;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if (!cfg_rdlock(cfg)) {
- cfg_perror_str = dgettext("cfg", CFG_NOTLOCKED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- bzero(buf, sizeof (buf));
- bzero(set, sizeof (set));
- bzero(tmpkey, sizeof (tmpkey));
- strcpy(tmpkey, key);
- section = strtok(tmpkey, ".");
- setp = strtok(NULL, ".");
- itemp = strtok(NULL, ".");
-
-#ifdef DEBUG_EXTRA
- if (!itemp)
- (void) fprintf(stderr, "cfg_get_cstring:section:%s setp=%s\n",
- section, setp);
- else
- (void) fprintf(stderr,
- "cfg_get_cstring:section:%s setp=%s fld=%s\n",
- section, setp, itemp);
-#endif
-
- table_offset = cfg_get_parser_offset(section);
- setnum = atoi(setp + 3);
- if ((setnum < 1) || (setnum > 0x7ffd)) {
- errno = EINVAL;
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
-
- /*
- * we have to figure out where this set is
- * in relation to other sets
- */
- relnum = 1;
- secnum = 0;
- numfound = 0;
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
- if (cfp->cf_head->h_state & CFG_HDR_INVALID) {
- if (!cfg_read(cfp)) {
- cfg_perror_str = dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- }
- while (numfound < setnum) {
- if ((*cfp->cf_pp->readcf)
- (cfp, buf, table_offset, relnum - secnum) == NULL) {
- secnum = relnum - 1;
- break;
- }
- if (cfg_filter_node(cfg, &chead[0], buf, section))
- numfound++;
-
- if (numfound == setnum)
- break;
-
- relnum++;
- }
- if (numfound == setnum)
- break;
- }
-
- /* Fail to find anything? */
- if (cfp >= &cfg->cf[2]) {
- errno = ESRCH;
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
-
- if (buf) {
- if (!itemp) {
- strncpy(value, buf, value_len);
- return (0);
- }
-
- if (itemp) {
- needed = cfg_get_item(&chead[0], section, itemp);
- p = strtok(buf, " ");
- while (p) {
- if (needed == pos) {
- errno = 0;
- if (*p == '-') {
- strcpy(value, "");
- return (0);
- } else {
- if (strlen(p) > value_len) {
- errno = E2BIG;
- cfg_perror_str =
- dgettext("cfg",
- strerror(errno));
- cfg_severity =
- CFG_ENONFATAL;
- return (-1);
- }
- }
- strncpy(value, p, value_len);
-
- return (pos);
- }
- p = strtok(NULL, " ");
- if (!p)
- break;
- pos++;
- }
- }
- }
- errno = ESRCH;
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_ENONFATAL;
- return (-1);
-}
-
-/*
- * cfg_find_cstring()
- * search for a string in the specified section
- * in the specified field(s)
- * if nfld is 0, then the string is searched for in
- * every field of the entry
- * the set number of the first occurence of target is returned
- * ie. if /dev/vx/rdsk/vol10 is found in sndr.set9, 9 will be returned
- * that is, of course, if the correct field was searched on.
- * -1 on error
- *
- */
-int
-cfg_find_cstring(CFGFILE *cfg, const char *target,
- const char *section, int numflds, ...)
-{
-
- char **list = NULL;
- va_list ap;
- char buf[CFG_MAX_BUF];
- char *field, *p;
- char **fldbuf = NULL;
- int i, j, rc;
- int pos = 1;
- int fieldnum;
- int nflds;
- int tbl_off;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if (numflds == 0) {
- nflds = cfg_get_num_flds(&chead[0], section, &tbl_off);
-
- } else {
- nflds = numflds;
- }
- if ((fldbuf = calloc(nflds, CFG_MAX_KEY)) == NULL) {
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if (numflds == 0) { /* search the whole string */
- if ((rc = cfg_get_section(cfg, &list, section)) <= 0) {
- for (i = 0; i < nflds; i++)
- free(fldbuf[i]);
- free(fldbuf);
- return (rc);
- }
- for (i = 0; i < rc; i++) {
- bzero(buf, sizeof (buf));
- strcpy(buf, list[i]);
- p = strtok(buf, " ");
- while (p) {
- if (strcmp(p, target) == 0) { /* we found it! */
- for (j = 0; j < rc; j++)
- free(list[j]);
- free(list);
- for (j = 0; j < nflds; j++)
- free(fldbuf[j]);
- free(fldbuf);
- return (i + 1);
- }
- p = strtok(NULL, " ");
- }
- }
- for (i = 0; i < nflds; i++)
- free(fldbuf[j]);
- for (i = 0; i < rc; i++)
- free(list[i]);
- free(fldbuf);
- free(list);
- return (0);
- }
-
- if ((rc = cfg_get_section(cfg, &list, section)) <= 0) {
- for (i = 0; i < nflds; i++)
- free(fldbuf[i]);
- free(fldbuf);
- return (rc);
- }
-
- va_start(ap, numflds);
- for (i = 0; i < numflds; i++) {
- fldbuf[i] = strdup(va_arg(ap, char *));
- }
-
- fldbuf[i] = NULL;
-
- for (j = 0; j < numflds; j++) {
- fieldnum = cfg_get_item(&chead[0], section, fldbuf[j]);
- for (i = 0; i < rc; i++) {
- bzero(buf, sizeof (buf));
- strcpy(buf, list[i]);
-
- field = strtok(buf, " ");
- pos = 1;
- while (pos < fieldnum) {
- field = strtok(NULL, " ");
- pos++;
- }
- if (field == NULL) {
- for (j = 0; j < numflds; j++)
- free(fldbuf[j]);
- for (j = 0; j < rc; j++)
- free(list[j]);
- free(fldbuf);
- free(list);
- return (-1);
- }
-
- if (strcmp(field, target) == 0) {
- for (j = 0; j < numflds; j++)
- free(fldbuf[j]);
- for (j = 0; j < rc; j++)
- free(list[j]);
- free(fldbuf);
- free(list);
-
- return (i + 1);
- }
-
- }
-
- }
- for (i = 0; i < nflds; i++)
- free(fldbuf[i]);
- for (i = 0; i < rc; i++)
- free(list[i]);
- free(fldbuf);
- free(list);
- return (0);
-}
-
-/*
- * cfg_put_cstring
- * modify entry or add an entry to configuration section
- * Key syntax supported
- * tag Add entry (in entirely) to config
- * tag.setn Add entry to setn If it exists overwrite old entry
- * tag.setn.field Change field in setn
- * value
- * string to change
- * NULL delete specified key
- *
- */
-
-int
-cfg_put_cstring(CFGFILE *cfg, const char *key, void *value, int val_len)
-{
- cfp_t *cfp;
- char buf[CFG_MAX_BUF];
- char newbuf[CFG_MAX_BUF];
- char *bufp;
- char tmpkey[CFG_MAX_KEY];
- char *section;
- char *setp;
- char *itemp;
- int nofield = 0;
- int noset = 0;
- int fldnum;
- int setnum = 0;
- int relnum;
- int secnum;
- int numfound;
- int addcnode = 1;
- int table_index;
- int table_offset;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- bzero(buf, sizeof (buf));
- strcpy(tmpkey, key);
- section = strtok(tmpkey, ".");
- setp = strtok(NULL, ".");
- itemp = strtok(NULL, ".");
-
- if (!cfg_wrlock(cfg)) {
- cfg_perror_str = dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if (!key) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
- if (value && val_len == 0) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
- if (!itemp)
- nofield++;
- if (!setp)
- noset++;
- else if (setp) {
- setnum = atoi(setp + 3);
- if (setnum < 1 || setnum > 0x7ffd) {
- errno = EINVAL;
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
- }
-
- table_offset = cfg_get_parser_offset(section);
-
- /*
- * we have to figure out where this set is
- * in relation to other sets
- */
- relnum = 1;
- secnum = 0;
- numfound = 0;
-
- if (setp && nofield) {
- char tmpbuf[CFG_MAX_BUF];
- int rc;
- int nflds;
- int got;
-
- /*
- * Set specified but no field
- */
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
- if (cfp->cf_head->h_state & CFG_HDR_INVALID) {
- if (!cfg_read(cfp)) {
- cfg_perror_str =
- dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- }
- while (numfound < setnum) {
- if ((*cfp->cf_pp->readcf)
- (cfp, tmpbuf, table_offset, relnum - secnum)
- == NULL) {
- secnum = relnum - 1;
- break;
- }
- if (cfg_filter_node(cfg, &chead[0], tmpbuf,
- section))
- numfound++;
-
- if (numfound == setnum)
- break;
-
- relnum++;
- }
- if (numfound == setnum)
- break;
- }
-
- /* Fail to find anything? */
- if (cfp >= &cfg->cf[2]) {
- errno = ESRCH;
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
-
- nflds = cfg_get_num_flds(&chead[0], section, &table_index);
-
- if (value == NULL) {
- /* Remove entry completely */
-
- rc = (*cfp->cf_pp->remcf)(cfp, table_index,
- relnum - secnum);
- if (rc < 0)
- return (rc);
- return (0);
- }
-
- got = cfg_cnt_flds(value);
- bzero(buf, sizeof (buf));
-
- strncpy(buf, " ", 1);
- if (strlen(value) > sizeof (buf) - 2) {
- errno = E2BIG;
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
- strncat(buf, value, val_len);
- if (got < nflds) {
- for (/* CSTYLED */; got < nflds; got++)
- strncat(buf, " - ", 3);
- } else if (got > nflds) {
- return (-1);
- } else {
- /* got == nflds, so cnode was included */
- addcnode = 0;
- }
-
- bufp = buf;
- if (addcnode) {
- cfg_insert_node(cfg, &chead[0], buf, section);
- }
-
- (*cfp->cf_pp->replacecf)(cfp, bufp, table_index,
- relnum - secnum);
-
- return (TRUE);
- }
-
- /*
- * Both Set and field are specified
- * needs to get current whole entry and old requested field
- * copy good fields to buf, replace new field in buf
- * move everything depending of new size
- * replace entry so set# does not change
- */
- if (setp && itemp) {
- int rc;
- int nflds;
- int cnodepos;
-
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
- if (cfp->cf_head->h_state & CFG_HDR_INVALID) {
- if (!cfg_read(cfp)) {
- cfg_perror_str =
- dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- }
- while (numfound < setnum) {
- if ((*cfp->cf_pp->readcf)
- (cfp, buf, table_offset, relnum - secnum)
- == NULL) {
- secnum = relnum - 1;
- break;
- }
- if (cfg_filter_node(cfg, &chead[0], buf,
- section))
- numfound++;
-
- if (numfound == setnum)
- break;
-
- relnum++;
- }
- if (numfound == setnum)
- break;
- }
-
- /* Fail to find anything? */
- if (cfp >= &cfg->cf[2]) {
- errno = ESRCH;
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_ENONFATAL;
- return (-1);
- }
-
- nflds = cfg_get_num_flds(&chead[0], section, &table_index);
- fldnum = cfg_get_item(&chead[0], section, itemp);
- bzero(newbuf, sizeof (newbuf));
- strncpy(newbuf, " ", 1);
-
- /* move good flds in */
- rc = cfg_fld_mov(newbuf, buf, 1, fldnum - 1);
- if (rc < 0)
- return (rc);
-
- /* move new fld in */
- strncat(newbuf, value, strlen(value));
- strcat(newbuf, " ");
-
- /* move remaining flds in */
- rc = cfg_fld_mov(newbuf, buf, fldnum + 1, nflds);
- if (rc < 0)
- return (rc);
-
- cnodepos = cfg_get_item(&chead[0], section, "cnode");
- if ((cnodepos >= 0) && strcmp(itemp, "cnode") != 0) {
- /* add cnode if user didn't specify it */
- cfg_insert_node(cfg, &chead[0],
- newbuf, section);
- }
-
- (*cfp->cf_pp->replacecf)(cfp, newbuf, table_index,
- relnum - secnum);
-
- return (TRUE);
- }
-
- if (noset) { /* blast entire thing in */
- int nflds;
- int got;
- int cnodepos;
-
- bufp = buf;
- if (!value) { /* we shouldn't be here */
- errno = EINVAL;
- return (-1);
- }
- strncat(buf, " ", 1);
- if (strlen(value) > sizeof (buf) - 2) {
- errno = E2BIG;
- return (-1);
- }
-
- strncat(buf, value, val_len);
- nflds = cfg_get_num_flds(&chead[0], section, &table_index);
- got = cfg_cnt_flds(value);
-
- cnodepos = cfg_get_item(&chead[0], section, "cnode");
- if (cnodepos < 0 || got >= cnodepos) {
- /* no cnode, or cnode was specified by caller */
- addcnode = 0;
- }
-
- if (got < nflds) {
- for (/* CSTYLED */; got < nflds; got++)
- strncat(buf, " - ", 3);
- } else if (got > nflds) {
- errno = EINVAL; /* specified too many fields */
- return (-1);
- } else {
- /* got == nflds, so cnode was included */
- addcnode = 0;
- }
-
- if (addcnode) {
- cfg_insert_node(cfg, &chead[0], buf, section);
- }
-
- /* Make sure we put this entry in the right database */
- if (cfg_is_cnode(cfg, &chead[0], buf, section) &&
- cfg->cf[1].cf_fd)
- cfp = &cfg->cf[1];
- else
- cfp = &cfg->cf[0];
-
- if (cfp->cf_head->h_state & CFG_HDR_INVALID) {
- if (!cfg_read(cfp)) {
- cfg_perror_str = dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- }
- if (cfp->cf_head->h_csize + strlen(buf) > CFG_DEFAULT_SSIZE) {
- errno = ENOSPC;
- return (-1);
- }
-
- (*cfp->cf_pp->addcf)(cfp, bufp, table_index);
-
- return (TRUE);
- }
-
- errno = EINVAL;
- cfg_perror_str = strerror(errno);
- cfg_severity = CFG_ENONFATAL;
- return (-1);
-}
-
-/*
- * cfg_encode_char
- *
- * Encode a single character into % + hex ascii value
- */
-static void
-cfg_encode_char(char *result, char ch)
-{
- *result++ = '%';
- *result++ = dectohex[ (ch >> 4) & 0xf ];
- *result++ = dectohex[ ch & 0xf ];
-}
-
-/*
- * cfg_decode_char
- *
- * Reverses cfg_encode_char
- */
-static char
-cfg_decode_char(char *code)
-{
- char retval;
- if (*code != '%') {
- return ('\0');
- }
- ++code;
- if (!isxdigit(*code))
- return ('\0');
- retval = (isdigit(*code)? *code - '0' : *code - 'a' + 10);
- retval <<= 4;
- ++code;
- if (!isxdigit(*code))
- return ('\0');
- retval |= (isdigit(*code)? *code - '0' : *code - 'a' + 10);
-
- return (retval);
-}
-
-/*
- * cfg_encode_option
- *
- * Transforms the key and value strings so that special characters
- * can be used within the options field.
- *
- * Returns:
- * Length of encoded string; -1 on failure
- */
-static int
-cfg_encode_string(char *str, char *output, int outlen)
-{
- char *mem, *p, *q;
- int curlen;
-
-
- /* first, scan through the tag string converting %-signs */
- p = str;
- q = output;
- curlen = 0;
- while (*p && curlen < outlen) {
- if (*p == '%') {
- if (curlen + 3 >= outlen) {
- return (-1);
- }
- cfg_encode_char(q, *p);
- curlen += 3;
- q += 3;
- } else {
- *q++ = *p;
- ++curlen;
- }
- ++p;
- }
- if (curlen < outlen)
- *q = '\0';
-
- /* now encode special characters */
- p = mem = strdup(output);
- q = output;
- curlen = 0;
- while (*p && curlen < outlen) {
- if (strchr(CHARS_TO_ENCODE, *p) != 0) {
- if (curlen + 3 >= outlen) {
- free(mem);
- return (-1);
- }
- cfg_encode_char(q, *p);
- curlen += 3;
- q += 3;
- } else {
- *q++ = *p;
- ++curlen;
- }
- ++p;
- }
- free(mem);
-
- if (curlen < outlen)
- *q = '\0';
- /* LINTED possible ptrdiff_t overflow */
- return (q - output);
-}
-
-/*
- * cfg_decode_option
- *
- * Given a string, decodes any %-encodes on it.
- */
-static void
-cfg_decode_string(char *str, char *output, int outlen)
-{
- char *p, *q;
- int curlen;
-
- p = str;
- q = output;
- curlen = 0;
- while (*p && curlen < outlen) {
- if (*p == '%') {
- char ch = cfg_decode_char(p);
- if (!ch) {
- *q++ = *p++;
- ++curlen;
- } else {
- *q++ = ch;
- p += 3;
- ++curlen;
- }
- } else {
- *q++ = *p++;
- ++curlen;
- }
- }
- if (curlen < outlen)
- *q = '\0';
-}
-
-/*
- * cfg_get_options
- * return first options set from basekey
- * Subsequent calls with basekey = NULL return next option if any
- * into tag and val
- * returns
- * true success and more options data
- * -1 no options data
- */
-
-int
-cfg_get_options(CFGFILE *cfg, int section, const char *basekey, char *tag,
- int tag_len, char *val, int val_len)
-{
- static char buf[CFG_MAX_BUF];
- char decode_buf[CFG_MAX_BUF];
- int rc;
- char *ttag, *tval;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- errno = ENOSYS;
- if (basekey == 0) {
- ttag = strtok(NULL, "=");
- } else {
- bzero(buf, CFG_MAX_BUF);
- if (section == CFG_SEC_CONF) {
- rc = cfg_get_cstring(cfg, basekey, buf, CFG_MAX_BUF);
- } else
- return (-1);
- if (rc < 0)
- return (rc);
- /* buf now contains raw options data */
- ttag = strtok(buf, "=");
- }
- tval = strtok(NULL, ";");
- if (!(tval) || !(ttag))
- return (-1);
- if ((strlen(tval) > val_len) || (strlen(ttag) > tag_len)) {
- errno = E2BIG;
- return (-1);
- }
- cfg_decode_string(tval, decode_buf, CFG_MAX_BUF);
- strncpy(val, decode_buf, val_len);
- cfg_decode_string(ttag, decode_buf, CFG_MAX_BUF);
- strncpy(tag, decode_buf, tag_len);
- errno = 0;
- return (TRUE);
-}
-
-/*
- * cfg_put_options
- *
- * Replaces existing tag with new val. If tag doesn't exist,
- * then it adds a new tag with the specified val.
- *
- * Return:
- * true success
- * -1 incorrect section, or read error from cfg DB
- */
-int
-cfg_put_options(CFGFILE *cfg, int section, const char *basekey, char *tag,
- char *val)
-{
- char buf[CFG_MAX_BUF];
- char encode_buf[CFG_MAX_BUF];
- char *p;
- int enclen;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- errno = ENOSYS;
- bzero(buf, CFG_MAX_BUF);
- if (section != CFG_SEC_CONF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- return (-1);
- }
- if (!tag || !*tag || !val || !*val)
- return (-1);
- if (cfg_get_cstring(cfg, basekey, buf, CFG_MAX_BUF) < 0) {
- /* cfg severity & perror_str set up cfg_get_cstring() */
- return (-1);
- }
- *encode_buf = ';';
- enclen = cfg_encode_string(tag, &encode_buf[1], CFG_MAX_BUF - 1) + 1;
- if (enclen < 1 || (enclen + 1) >= CFG_MAX_BUF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", "Buffer too small");
- return (-1);
- }
- encode_buf[enclen] = '=';
- encode_buf[enclen + 1] = '\0';
-
- /* check the start of the string */
- if (strncmp(buf, &encode_buf[1], enclen) == 0) {
- /* locate the end of this option */
- p = strchr(buf, ';');
- if (p && *(p + 1) != '\0') {
- /* add the new tag to the end */
- ++p;
- strcat(p, &encode_buf[1]);
- } else {
- /* completely overwrite the existing tag */
- p = buf;
- strcpy(p, &encode_buf[1]);
- }
- if (cfg_encode_string(val, encode_buf, CFG_MAX_BUF) < 0) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", "Buffer too small");
- return (-1);
- }
- strcat(p, encode_buf);
- strcat(p, ";");
- if (cfg_put_cstring(cfg, basekey, p, strlen(p)) < 0) {
- /* severity & perror_str set by cfg_put_cstring */
- return (-1);
- }
- errno = 0;
- return (TRUE);
- }
-
- /* it's hiding somewhere inside... */
- p = strstr(buf, encode_buf);
- if (p) {
- /* delete the old value */
- char *q = strchr(p + 1, ';');
- if (q) {
- strcpy(p + 1, q + 1);
- } else {
- *p = '\0';
- }
- strcat(buf, &encode_buf[1]);
- } else if (*buf) {
- strcat(buf, &encode_buf[1]);
- } else {
- strcpy(buf, &encode_buf[1]);
- }
- enclen = cfg_encode_string(val, encode_buf, CFG_MAX_BUF);
- if (enclen < 0 || (strlen(buf) + enclen) >= CFG_MAX_BUF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", "Buffer too small");
- return (-1);
- }
- strcat(buf, encode_buf);
- strcat(buf, ";");
- if (cfg_put_cstring(cfg, basekey, buf, CFG_MAX_BUF) < 0) {
- /* severity & perror_str set by cfg_put_cstring */
- return (-1);
- }
- errno = 0;
- return (TRUE);
-}
-
-/*
- * cfg_get_single_option
- *
- * Scans the options string for the specified option and returns
- * the decoded value
- *
- * Return:
- * true success
- * -1 incorrect section, or read error from cfg DB
- */
-int
-cfg_get_single_option(CFGFILE *cfg, int section, const char *basekey, char *tag,
- char *val, int val_len)
-{
- char buf[CFG_MAX_BUF];
- char encode_buf[CFG_MAX_BUF];
- char *p, *q;
- int enclen;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- errno = ENOSYS;
- bzero(buf, CFG_MAX_BUF);
- if (section != CFG_SEC_CONF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- return (-1);
- }
- if (cfg_get_cstring(cfg, basekey, buf, CFG_MAX_BUF) < 0) {
- /* severity & perror_str set by cfg_get_cstring */
- return (-1);
- }
-
- *encode_buf = ';';
- enclen = cfg_encode_string(tag, &encode_buf[1], CFG_MAX_BUF - 1) + 1;
- if (enclen < 1 || (enclen + 1) >= CFG_MAX_BUF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", "Buffer too small");
- return (-1);
- }
- encode_buf[enclen] = '=';
- encode_buf[enclen + 1] = '\0';
-
- /* check the start of the string */
- if (strncmp(buf, &encode_buf[1], enclen) == 0) {
- p = strchr(buf, '=');
- if (!p) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", "Option not found");
- return (-1);
- }
- ++p;
- q = strchr(p, ';');
- if (q) {
- *q = '\0';
- }
- cfg_decode_string(p, val, val_len);
- errno = 0;
- return (TRUE);
- }
-
- /* it's hiding somewhere inside... */
- p = strstr(buf, encode_buf);
- if (p) {
- p += enclen + 1;
- q = strchr(p, ';');
- if (q) {
- *q = '\0';
- }
- cfg_decode_string(p, val, val_len);
- errno = 0;
- return (TRUE);
- }
-
- /* key not found */
- return (-1);
-
-}
-
-/*
- * cfg_del_option
- *
- * Removes a single key=val pair from the specified option field
- *
- * Return:
- * true success
- * -1 unable to update config
- */
-int
-cfg_del_option(CFGFILE *cfg, int section, const char *basekey, char *tag)
-{
- char buf[CFG_MAX_BUF];
- char encode_buf[CFG_MAX_BUF];
- char *p, *q;
- int enclen, rc;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- bzero(buf, CFG_MAX_BUF);
- if (section != CFG_SEC_CONF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- return (-1);
- }
- if (cfg_get_cstring(cfg, basekey, buf, CFG_MAX_BUF) < 0) {
- /* severity & perror_str are set by cfg_get_cstring */
- return (-1);
- }
-
- *encode_buf = ';';
- enclen = cfg_encode_string(tag, &encode_buf[1], CFG_MAX_BUF - 1) + 1;
- if (enclen < 1 || (enclen + 1) >= CFG_MAX_BUF) {
- cfg_severity = CFG_ENONFATAL;
- cfg_perror_str = dgettext("cfg", "Buffer too small");
- return (-1);
- }
- encode_buf[enclen] = '=';
- encode_buf[enclen + 1] = '\0';
-
- /* check the start of the string */
- if (strncmp(buf, &encode_buf[1], enclen) == 0) {
- p = strchr(buf, ';');
- if (p && (*(p + 1) != '\0')) {
- rc = cfg_put_cstring(cfg, basekey, p + 1,
- strlen(p + 1));
- } else {
- rc = cfg_put_cstring(cfg, basekey, "-", 1);
- }
- /* severity & perror_str are set by cfg_put_cstring */
- return (rc);
- }
-
- /* sigh */
- p = strstr(buf, encode_buf);
- if (!p) {
- /* already removed */
- return (TRUE);
- }
- q = strchr(p + 1, ';');
-
- /*
- * Now the string looks like:
- * | first few options | *p | option to remove | *q | rest | '\0'
- */
-
- if (!q) {
- /* hum... */
- *p = '\0';
- } else {
- strcpy(p, q);
- }
-
- return (cfg_put_cstring(cfg, basekey, buf, strlen(buf)));
-}
-
-static void
-cfg_set_memorymap(cfp_t *cfp)
-{
- cfgheader_t *hd = cfp->cf_head;
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "callocing %d for initial reads\n", hd->h_csize);
-#endif
-
- hd->h_ccopy1 = (char *)calloc(hd->h_csize, sizeof (char));
- hd->h_ccopy2 = (char *)calloc(hd->h_csize, sizeof (char));
- hd->h_sizes1 = (int *)calloc(CFG_DEFAULT_PSIZE, sizeof (int));
- hd->h_sizes2 = (int *)calloc(CFG_DEFAULT_PSIZE, sizeof (int));
-}
-
-/*
- * cfg_init_header
- * fill in default header info
- */
-static void
-cfg_init_header(cfp_t *cfp)
-{
- time_t tloc;
- cfgheader_t *hd = cfp->cf_head;
-
- hd->h_magic = (int32_t)CFG_NEW_MAGIC;
- hd->h_stamp = time(&tloc);
- hd->h_lock = 0;
- /* parser config */
- hd->h_parsesize = 0;
- hd->h_parseoff = 0;
- hd->h_csize = 0;
- hd->h_psize = 0;
- hd->h_cfgs = NULL;
- hd->h_ncfgs = 0;
- hd->h_seq1 = hd->h_seq2 = 1;
- bzero(hd->h_cfgsizes, MAX_CFG * sizeof (int));
-}
-/*
- * cfg_read
- * read header and all sections of configuration file
- * gets new data for incore copy
- * removes invalid header state
- * works even if config and persistent sections are empty
- *
- */
-static int
-cfg_read(cfp_t *cfp)
-{
- int rc;
- cfgheader_t *hd;
- int readsize = 0;
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_read\n");
-#endif
-
- if (!cfp->cf_head) {
- if ((hd = calloc(1, sizeof (*hd))) == NULL)
- return (FALSE);
-#ifdef DEBUG_HDR
- (void) fprintf(stderr, "initial cfg header read\n");
-#endif
- cfp->cf_head = hd;
- }
-
- if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg: seek header failed\n");
-#endif
- return (FALSE);
- }
-
- rc = (*cfp->cf_pp->read)(cfp, (char *)cfp->cf_head, 4);
- if (rc < 4) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg: read magic number failed\n");
-#endif
- return (FALSE);
- }
-
- if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg: seek header failed\n");
-#endif
- return (FALSE);
- }
-
- rc = (*cfp->cf_pp->read)(cfp, (char *)cfp->cf_head, sizeof (*hd));
- if (rc < sizeof (*hd)) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg: read header failed\n");
-#endif
- return (FALSE);
- }
-
- cfp->cf_head->h_cfgs = NULL;
- cfg_set_memorymap(cfp);
- if (cfp->cf_head->h_magic != CFG_NEW_MAGIC) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg_read: wrong MAGIC number %x\n",
- cfp->cf_head->h_magic);
-#endif
- return (FALSE);
- }
-
- cfp->cf_head->h_state &= ~(CFG_HDR_INVALID);
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "reading parser\n");
-#endif
- rc = (*cfp->cf_pp->read)(cfp, (char *)cfp->cf_mapped,
- CFG_DEFAULT_PARSE_SIZE);
- if (rc < sizeof (*hd)) {
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: read parse config failed\n");
-#endif
- return (FALSE);
- }
-
- readsize = cfp->cf_head->h_csize;
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "reading copy1 readsize = %d\n", readsize);
-#endif
- rc = (*cfp->cf_pp->read)(cfp, (char *)cfp->cf_head->h_ccopy1,
- readsize);
- if (rc < 0) {
- /* don't fail just return */
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: read ccopy1 section failed\n");
-#endif
- return (FALSE);
- }
-
- if ((*cfp->cf_pp->seek)
- (cfp, CFG_DEFAULT_SSIZE - rc, SEEK_CUR) < 0) {
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: seek (SEEK_CUR) failed\n");
-#endif
- return (FALSE);
- }
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "reading copy2 readsize = %d\n", readsize);
-#endif
-
- rc = (*cfp->cf_pp->read)(cfp, (char *)cfp->cf_head->h_ccopy2,
- readsize);
- if (rc < 0) {
- /* don't fail just return */
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: read ccopy2 section failed\n");
-#endif
- return (FALSE);
- }
-
- /* read the sizes of the lists from disk */
- if ((*cfp->cf_pp->seek)
- (cfp, CFG_DEFAULT_SSIZE - rc, SEEK_CUR) < 0) {
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: seek (SEEK_CUR) failed\n");
-#endif
- return (FALSE);
- }
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "reading sizes\n");
-#endif
- rc = (*cfp->cf_pp->read)(cfp, (int *)cfp->cf_head->h_sizes1,
- CFG_DEFAULT_PSIZE);
- if (rc < 0) {
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: read h_sizes1 failed\n");
-#endif
- return (FALSE);
- }
-
- rc = (*cfp->cf_pp->read)(cfp, (int *)cfp->cf_head->h_sizes2,
- CFG_DEFAULT_PSIZE);
- if (rc < 0) {
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg: read h_sizes2 failed\n");
-#endif
- return (FALSE);
- }
-
- /*
- * If initial or invalid sequence, use first section
- */
- if ((cfp->cf_head->h_seq1 <= 0) && (cfp->cf_head->h_seq2 <= 0)) {
- cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy1;
- cfp->cf_head->h_sizes = cfp->cf_head->h_sizes1;
- }
-
- if (cfp->cf_head->h_seq1 >= cfp->cf_head->h_seq2) {
- cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy1;
- cfp->cf_head->h_sizes = cfp->cf_head->h_sizes1;
- } else {
- cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy2;
- cfp->cf_head->h_sizes = cfp->cf_head->h_sizes2;
- }
-
-#ifdef DEBUG_LIB
- dump_status(cfp, "cfg_read");
-#endif
-
- return (TRUE);
-}
-
-/*
- * cfg_lock
- * Read-write locking of the configuration
- * reads into core all sections
- * builds parser trees for each section
- * Returns: TRUE if the lock was acquired, FALSE otherwise.
- */
-int
-cfg_lock(CFGFILE *cfg, CFGLOCK mode)
-{
- cfp_t *cfp;
- int is_locked = 0;
- int rc;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- if (mode == CFG_UPGRADE) {
- mode = CFG_WRLOCK;
- }
-
- if (mode == CFG_WRLOCK && (cfg->cf[0].cf_flag & CFG_RDONLY)) {
- goto fail;
- }
-
- /*
- * if you don't even give me the right lock request,
- * why should I give you one?
- */
- if (mode != CFG_RDLOCK && mode != CFG_WRLOCK)
- goto fail;
-
- if (cfg_lockd) {
- if (mode == CFG_WRLOCK)
- cfg_lockd_wrlock();
- else
- cfg_lockd_rdlock();
- is_locked = 1;
- } else {
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_lock\n");
-#endif
- /* Lock is always based on local file pointer */
- cfg->cf[1].cf_lock = cfg->cf[0].cf_lock = cfg->cf[0].cf_fd;
-
- if (!((cfg->cf[0].cf_flag & CFG_RDONLY) &&
- (mode == CFG_RDLOCK))) {
-
- struct flock lk = {0};
- lk.l_type = (mode == CFG_RDLOCK ? F_RDLCK : F_WRLCK);
- lk.l_whence = SEEK_SET;
- lk.l_start = (off_t)0;
- lk.l_len = (off_t)0;
-
- if (fcntl(cfg->cf[0].cf_lock, F_SETLKW, &lk) < 0)
- goto fail;
- }
- }
-
- /* Determine number of files open */
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
- if ((cfp->cf_head) &&
- (cfp->cf_head->h_state & CFG_HDR_INVALID)) {
- if ((rc = cfg_hdrcmp(cfp)) == 0) {
-#ifdef DEBUG_HDR
- (void) fprintf(stderr,
- "cfg header match, skipping re-read\n");
-#endif
- cfp->cf_head->h_state |= CFG_HDR_RDLOCK;
- if (mode == CFG_WRLOCK)
- cfp->cf_head->h_state |= CFG_HDR_WRLOCK;
-
- cfp->cf_head->h_state &= ~(CFG_HDR_INVALID);
- continue;
- }
-#ifdef DEBUG_HDR
- (void) fprintf(stderr, "re-reading cfg, header mismatch\n");
-#endif
- /*
- * dump what we have, info is stale
- */
- cfg_free_cfglist(cfp);
- cfg_free_parser_tree();
-
- if (cfp->cf_head->h_ccopy1) {
- free(cfp->cf_head->h_ccopy1);
- cfp->cf_head->h_ccopy1 = NULL;
- }
- if (cfp->cf_head->h_ccopy2) {
- free(cfp->cf_head->h_ccopy2);
- cfp->cf_head->h_ccopy2 = NULL;
- }
- if (cfp->cf_head->h_sizes1) {
- free(cfp->cf_head->h_sizes1);
- cfp->cf_head->h_sizes1 = NULL;
- }
- if (cfp->cf_head->h_sizes2) {
- free(cfp->cf_head->h_sizes2);
- cfp->cf_head->h_sizes2 = NULL;
- }
-
- if (cfp->cf_head)
- free(cfp->cf_head);
- cfp->cf_head = NULL;
- }
-
- if (cfp->cf_head == NULL) {
- if (!cfg_read(cfp)) {
- if (cfp->cf_head != NULL)
- cfg_init_header(cfp);
- else
- goto fail;
- } else {
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr,
- "reading parser config\n");
-#endif
- /* build parser trees */
- cfg_read_parser_config(cfp);
- }
-
- }
- cfp->cf_head->h_state |= CFG_HDR_RDLOCK;
- if (mode == CFG_WRLOCK) {
- if (cfp->cf_head->h_seq1 >= cfp->cf_head->h_seq2) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr,
- "cfg_lock: WRLOCK copying 1 to 2\n");
-#endif
- memcpy(cfp->cf_head->h_ccopy2,
- cfp->cf_head->h_ccopy1,
- cfp->cf_head->h_csize);
- memcpy(cfp->cf_head->h_sizes2,
- cfp->cf_head->h_sizes1,
- CFG_DEFAULT_PSIZE);
-
- cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy2;
- cfp->cf_head->h_sizes = cfp->cf_head->h_sizes2;
- } else {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr,
- "cfg_lock: WRLOCK copying 2 to 1\n");
-#endif
- memcpy(cfp->cf_head->h_ccopy1,
- cfp->cf_head->h_ccopy2,
- cfp->cf_head->h_csize);
- memcpy(cfp->cf_head->h_sizes1,
- cfp->cf_head->h_sizes2,
- CFG_DEFAULT_PSIZE);
-
- cfp->cf_head->h_cparse = cfp->cf_head->h_ccopy1;
- cfp->cf_head->h_sizes = cfp->cf_head->h_sizes1;
- }
-
- cfp->cf_head->h_state |= CFG_HDR_WRLOCK;
- }
-
- if (cfg_map_cfglists(cfp) < 0) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg: map_cfglists failed\n");
-#endif
- goto fail;
- }
-
-#ifdef DEBUG_LIB
- dump_status(cfp, "cfg_lock");
-#endif
- }
-
- return (TRUE);
-
-fail:
- if (is_locked) {
- cfg_lockd_unlock();
- }
- cfg_perror_str = dgettext("cfg", CFG_EGENERIC);
- cfg_severity = CFG_ENONFATAL;
- return (FALSE);
-}
-
-/*
- * Unlock the database
- */
-void
-cfp_unlock(cfp_t *cfp)
-{
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_unlock\n");
-#endif
- if (cfg_lockd) {
- cfg_lockd_unlock();
- } else {
- struct flock lk = {0};
- lk.l_type = F_UNLCK;
- lk.l_whence = SEEK_SET;
- lk.l_start = (off_t)0;
- lk.l_len = (off_t)0;
- (void) fcntl(cfp->cf_lock, F_SETLKW, &lk);
- }
-
- if (cfp->cf_head != NULL) {
- cfp->cf_head->h_state &= ~(CFG_HDR_RDLOCK|CFG_HDR_WRLOCK);
- cfp->cf_head->h_state |= CFG_HDR_INVALID;
- }
-}
-void
-cfg_unlock(CFGFILE *cfg)
-{
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return;
- }
-
- cfp_unlock(&cfg->cf[0]);
- cfp_unlock(&cfg->cf[1]);
-}
-
-/*
- * Test for a read lock, set errno if failed.
- */
-static int
-cfg_rdlock(CFGFILE *cfg)
-{
- int rc;
- cfp_t *cfp;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- /* Determine number of files open */
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd)
- continue;
- if (cfp->cf_head == NULL) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg_rdlock: cf_head == NULL\n");
-#endif
- /*
- * 6335583, if header == NULL,
- * we can't call cfg_read to fill the header again
- * since it will change the lock state to
- * CFG_HDR_WRLOCK and dscfg will be the processer
- * that hold the lock,
- * just returning a FALSE if the case,
- * then retrieve the lock state from flock structure.
- */
- rc = FALSE;
- break;
- } else {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg_rdlock: cf_head != NULL\n");
-#endif
- if ((cfp->cf_head->h_state & CFG_HDR_RDLOCK)
- == CFG_HDR_RDLOCK) {
- rc = TRUE;
- } else {
- rc = FALSE;
- break;
- }
- }
- }
-
- if (!rc)
- errno = EPERM;
-
- return (rc);
-}
-
-/*
- * Test for a write lock, set errno if failed.
- */
-static int
-cfg_wrlock(CFGFILE *cfg)
-{
- int rc;
- cfp_t *cfp;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- /* Determine number of files open */
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd)
- continue;
- if (cfp->cf_head == NULL) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg wrlock: cf_head == NULL\n");
-#endif
- /*
- * 6335583, see comments on cfg_rdlock
- */
- rc = FALSE;
- break;
- } else {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg wrlock: cf_head != NULL\n");
-#endif
- if ((cfp->cf_head->h_state & CFG_HDR_WRLOCK)
- == CFG_HDR_WRLOCK) {
- rc = TRUE;
- } else {
- rc = FALSE;
- break;
- }
- }
- }
-
- if (!rc)
- errno = EPERM;
-
- return (rc);
-}
-
-/*
- * cfg_get_lock
- * Find lock status of CFG database.
- * Returns: TRUE and sets lock and pid if the lock is held, FALSE otherwise.
- */
-int
-cfg_get_lock(CFGFILE *cfg, CFGLOCK *lock, pid_t *pid)
-{
- struct flock lk;
- int rc;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- if (cfg_lockd) {
- switch (cfg_lockedby(pid)) {
- case LOCK_READ:
- *lock = CFG_RDLOCK;
- return (TRUE);
- case LOCK_WRITE:
- *lock = CFG_WRLOCK;
- return (TRUE);
- case LOCK_NOTLOCKED:
- default:
- return (FALSE);
- }
- } else {
- if (cfg_wrlock(cfg)) {
- *lock = CFG_WRLOCK;
- *pid = getpid();
- return (TRUE);
- }
-
- if (cfg_rdlock(cfg)) {
- *lock = CFG_RDLOCK;
- *pid = getpid();
- return (TRUE);
- }
- }
- /* Lock is always based on local file pointer */
- cfg->cf[1].cf_lock = cfg->cf[0].cf_lock = cfg->cf[0].cf_fd;
-
- bzero(&lk, sizeof (lk));
- lk.l_type = F_WRLCK;
- lk.l_whence = SEEK_SET;
- lk.l_start = (off_t)0;
- lk.l_len = (off_t)0;
-
- if (fcntl(cfg->cf[0].cf_lock, F_GETLK, &lk) < 0)
- rc = FALSE;
- else {
- if (lk.l_type == F_UNLCK)
- rc = FALSE;
- else {
- rc = TRUE;
- *pid = lk.l_pid;
- *lock = lk.l_type == F_WRLCK ? CFG_WRLOCK : CFG_RDLOCK;
- }
- }
-
- return (rc);
-}
-
-/*
- * cfg_commit
- * Write modified version of header, configuration and persistent
- * data using 2 stage commit.
- * If no valid data is found in header, it is assumed to be an initial
- * write and we will create the default header (could be dangerous)
- * another tricky part, if we are doing an upgrade we may be dealing
- * with an old database. we need to take care seeking and writing
- * until such time that it is upgraded.
- *
- * Mutual exclusion is checked using cfg_lock
- */
-
-int
-cfg_commit(CFGFILE *cfg)
-{
- cfp_t *cfp;
- int rc;
- time_t tloc;
- int section;
- int wrsize, *ip;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- if (!cfg_wrlock(cfg))
- return (FALSE);
-
- /* Determine number of files open */
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd)
- continue;
-
- /*
- * lets put everything back into one char *
- */
- cfg_replace_lists(cfp);
-
- if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) {
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "cfg: seek header failed\n");
-#endif
- return (FALSE);
- }
-
- cfp->cf_head->h_size = cfp->cf_head->h_parsesize
- + cfp->cf_head->h_csize + cfp->cf_head->h_psize;
- cfp->cf_head->h_stamp = time(&tloc);
-
- /* seeking into database */
- if ((*cfp->cf_pp->seek)(cfp, sizeof (cfgheader_t),
- SEEK_CUR) < 0)
- return (FALSE);
-
- if (cfp->cf_head->h_ccopy1 == cfp->cf_head->h_cparse) {
- if (cfp->cf_head->h_seq1 < 0)
- cfp->cf_head->h_seq1 = 1;
- else
- cfp->cf_head->h_seq1 = cfp->cf_head->h_seq2 + 1;
- section = 1;
- } else {
- if (cfp->cf_head->h_seq2 < 0)
- cfp->cf_head->h_seq2 = 1;
- else
- cfp->cf_head->h_seq2 = cfp->cf_head->h_seq1 + 1;
- section = 2;
- }
-#ifdef DEBUG_LIB
- dump_status(cfp, "cfg_commit");
-#endif
- rc = (*cfp->cf_pp->write)(cfp, cfp->cf_mapped,
- CFG_DEFAULT_PARSE_SIZE);
-#ifdef DEBUG
- if (rc < 0) {
- (void) fprintf(stderr,
- "parse commit: rc %d h_parsesize %d\n",
- rc, cfp->cf_head->h_parsesize);
- }
-#endif
- if (section == 1) {
- rc = (*cfp->cf_pp->write) (cfp, cfp->cf_head->h_ccopy1,
- cfp->cf_head->h_csize);
-#ifdef DEBUG
- if (rc < 0) {
- (void) fprintf(stderr,
- "csection commit 1: rc %d h_csize %d\n",
- rc, cfp->cf_head->h_csize);
- }
-#endif
- if ((*cfp->cf_pp->seek)
- (cfp, (2 * CFG_DEFAULT_SSIZE) - rc, SEEK_CUR) < 0)
- return (FALSE);
-
- /*
- * limit the write to only what we need
- */
- ip = cfp->cf_head->h_sizes1;
- for (wrsize = 0; *ip; ip += *ip + 1)
- wrsize += *ip + 1;
-
- rc = (*cfp->cf_pp->write)(cfp, cfp->cf_head->h_sizes1,
- wrsize * sizeof (int));
-#ifdef DEBUG
- if (rc < 0) {
- (void) fprintf(stderr,
- "cfg: write list sizes1 failed rc\n");
- }
-#endif
- } else {
- if ((*cfp->cf_pp->seek)(cfp, CFG_DEFAULT_SSIZE,
- SEEK_CUR) < 0)
- return (FALSE);
-
- rc = (*cfp->cf_pp->write)(cfp, cfp->cf_head->h_ccopy2,
- cfp->cf_head->h_csize);
-#ifdef DEBUG
- if (rc < 0) {
- (void) fprintf(stderr,
- "csection commit 2: rc %d h_csize %d\n",
- rc, cfp->cf_head->h_csize);
- }
-#endif
- if ((*cfp->cf_pp->seek)
- (cfp, (CFG_DEFAULT_SSIZE + CFG_DEFAULT_PSIZE) - rc,
- SEEK_CUR) < 0)
- return (FALSE);
-
- /*
- * limit the write to only what we need
- */
- ip = cfp->cf_head->h_sizes2;
- for (wrsize = 0; *ip; ip += *ip + 1)
- wrsize += *ip + 1;
-
- rc = (*cfp->cf_pp->write)(cfp, cfp->cf_head->h_sizes2,
- wrsize * sizeof (int));
-#ifdef DEBUG
- if (rc < 0) {
- (void) fprintf(stderr,
- "cfg: write list sizes2 failed\n");
- }
-#endif
-
- }
-
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr,
- "writing h_csize %d\n", cfp->cf_head->h_csize);
-#endif
- if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0)
- return (FALSE);
-
- cfp->cf_head->h_size = cfp->cf_head->h_parsesize +
- cfp->cf_head->h_csize + cfp->cf_head->h_psize;
-
- rc = (*cfp->cf_pp->write)(cfp, cfp->cf_head,
- sizeof (cfgheader_t));
- if (rc < 0) {
- cfg_perror_str = dgettext("cfg",
- "cfg_commit: header write failed");
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
- }
-
- return (TRUE);
-}
-
-/*
- * cfg_rewind
- * rewind internal file pointer for specified section
- * empty now, rewind not necessary. But don't break
- * old code.
- */
-/*ARGSUSED*/
-void
-cfg_rewind(CFGFILE *cfg, int section)
-{
- switch (section) {
- case CFG_SEC_CONF:
- break;
- case CFG_SEC_ALL:
- break;
- };
-}
-
-/*
- * cfg_location
- * set or return the default location file to
- * determine the partition name of the configuration partition
- * location is stored in well known file location
- */
-char *
-cfg_location(char *location, int mode, char *altroot)
-{
- int fd;
- int fmode;
- int rc;
- char wellknown[NSC_MAXPATH];
- char loc[NSC_MAXPATH];
-
- if (mode == CFG_LOC_GET_LOCAL) {
- return (CFG_LOCAL_LOCATION);
- } else if (mode == CFG_LOC_GET_CLUSTER) {
- fmode = O_RDONLY;
- } else {
- fmode = O_RDWR | O_CREAT;
- }
-
- if (altroot) {
- strcpy(wellknown, altroot);
- strcat(wellknown, CFG_CLUSTER_LOCATION);
- } else
- strcpy(wellknown, CFG_CLUSTER_LOCATION);
-
- fd = open(wellknown, fmode, 0644);
- if (fd < 0) {
- cfg_perror_str = dgettext("cfg", strerror(errno));
- cfg_severity = CFG_ENONFATAL;
- return (NULL);
- }
-
- if (mode == CFG_LOC_SET_CLUSTER) {
- if (location == NULL || (strlen(location) > NSC_MAXPATH)) {
- cfg_perror_str = dgettext("cfg",
- "cfg_location: filename too big or missing");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
-
- /*
- * 5082142
- * If we're in a cluster, make sure that the config location
- * is a raw device. Using non-raw did devices in a cluster
- * can result in data corruption, since inconsistent data
- * may reside in the block cache on one node, but has not
- * been flushed to disk.
- */
- if (cfg_iscluster() > 0) {
- struct stat dscfg_stat;
- if (stat(location, &dscfg_stat) != 0) {
- cfg_perror_str = dgettext("cfg",
- "Unable to access dscfg location");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
- if (!S_ISCHR(dscfg_stat.st_mode)) {
- cfg_perror_str = dgettext("cfg",
- "dscfg location must be a raw device");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
- }
-
- if (ftruncate(fd, 0) < 0)
- return (NULL);
-
- rc = write(fd, location, strlen(location));
- if (rc < 0) {
- cfg_perror_str = dgettext("cfg",
- "cfg_location: write to well known failed");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
- bzero(config_file, sizeof (config_file));
- }
- if (lseek(fd, 0, SEEK_SET) < 0)
- return (NULL);
-
- bzero(config_file, sizeof (config_file));
- rc = read(fd, config_file, sizeof (config_file));
- if (rc < 0) {
- cfg_perror_str = dgettext("cfg",
- "cfg_location: read from well known failed");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
- close(fd);
- if (altroot) {
- strcpy(loc, altroot);
- strcat(loc, config_file);
- bzero(config_file, sizeof (config_file));
- strcpy(config_file, loc);
- }
-
- /*
- * scan string out of config_file, to strip whitespace
- */
- sscanf(config_file, "%s", loc);
- strcpy(config_file, loc);
-
- return (config_file);
-}
-
-/*
- * cfg_update_parser_config
- * If tag and key exist return -1
- *
- * XXX Currently does not append new field to existing parser rule
- */
-
-int
-cfg_update_parser_config(CFGFILE *cfg, const char *key, int section)
-{
- cfp_t *cfp;
- int size;
- char buf[CFG_MAX_BUF];
- struct parser *tbl;
- char tmpkey[CFG_MAX_KEY];
- char *ky, *fld;
- errno = 0;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- cfp = FP_SUN_CLUSTER(cfg);
- if (!cfg_wrlock(cfg))
- return (-1);
-
- bzero(buf, CFG_MAX_BUF);
- bzero(tmpkey, sizeof (tmpkey));
- strcpy(tmpkey, key);
- if (section == CFG_PARSE_CONF) {
- strcat(buf, "C:");
- tbl = chead;
- } else {
- errno = EINVAL;
- return (-1);
- }
- ky = strtok(tmpkey, ".");
- fld = strtok(NULL, ".");
- while (fld) {
- size = cfg_get_item(tbl, ky, fld);
-
- /*
- * Assure we are loading a clean table, with do duplicates
- * based on our File Descriptor
- */
- if (chead_loaded && (chead_loaded != cfp->cf_fd)) {
- if (size <= 0)
- return (-1);
- } else {
- if (size > 0)
- return (-1);
- }
- fld = strtok(NULL, ".");
- }
- size = strlen(key) + 2;
- strncat(buf, key, size);
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "update parser config %s size %d\n", buf, size);
-#endif
- if ((size + cfp->cf_head->h_parseoff) > CFG_DEFAULT_PARSE_SIZE) {
- cfg_perror_str = dgettext("cfg",
- "cfg_update_parser_config: header overrun");
- cfg_severity = CFG_EFATAL;
-#ifdef DEBUG_LIB
- (void) fprintf(stderr, "update parser config: "
- "overrun siz %d poff %d parsesize %d\n",
- size, cfp->cf_head->h_parseoff, cfp->cf_head->h_parsesize);
-#endif
- errno = E2BIG;
- return (-1);
- }
- bcopy(buf, (cfp->cf_mapped + cfp->cf_head->h_parseoff), size);
- cfp->cf_head->h_parseoff += size;
- cfp->cf_head->h_state |= CFG_HDR_INVALID;
- if (cfp->cf_mapped[cfp->cf_head->h_parseoff - 1] != '\n') {
- cfp->cf_mapped[cfp->cf_head->h_parseoff] = '\n';
- cfp->cf_head->h_parseoff++;
- }
- cfp->cf_head->h_parsesize = cfp->cf_head->h_parseoff;
- cfg_read_parser_config(cfp);
- return (TRUE);
-}
-/*
- * cfg_read_parser_config
- * reads parser config from file
- * converts it to internal tree for parsing
- * chead for configuration parser entries
- *
- */
-static
-void
-cfg_read_parser_config(cfp_t *cfp)
-{
- struct lookup *p, *q;
- struct parser *thead;
- int off, foff;
- char *part;
- char *key;
- char *fld;
- int fldnum;
- char c;
- char buf[CFG_MAX_BUF];
- int i = 0;
- int n = 0;
-
- off = foff = 0;
- /*CONSTCOND*/
- while (TRUE) {
- off = 0;
- bzero(buf, CFG_MAX_BUF);
- /* LINTED it assigns value to c */
- while (c = cfp->cf_mapped[foff++]) {
- if (c == '\n')
- break;
- buf[off++] = c;
- }
- part = strtok(buf, ":");
- if (!part)
- break;
- if (*part == 'C') {
- thead = chead;
- n = i;
- }
- key = strtok(NULL, ".");
- if (!key)
- break;
- strcpy(thead[n].tag.l_word, key);
- thead[n].tag.l_value = 0;
- thead[n].fld = NULL;
- fldnum = 1;
- while ((fld = strtok(NULL, ".")) != NULL) {
- p = thead[n].fld;
- if (p == NULL) {
- q = thead[n].fld = calloc(1,
- sizeof (struct lookup));
- } else {
- for (q = thead[n].fld; q; q = q->l_next)
- p = q;
- q = calloc(1, sizeof (struct lookup));
- p->l_next = q;
- }
- strcpy(q->l_word, fld);
- q->l_value = fldnum;
- q->l_next = NULL;
-#ifdef DEBUG_EXTRA
- (void) fprintf(stderr,
- "read parser: q: word %s value %d\n",
- q->l_word, q->l_value);
-#endif
- fldnum++;
- }
- if (*part == 'C')
- i++;
- }
-
- /* All done, indicate parser table is loaded */
- if (i && (chead_loaded == 0))
- chead_loaded = cfp->cf_fd;
-
- /*
- * before I go and alloc, why am I here?
- * do I need a bunch of cfglists, or do I just
- * need to accommodate a just added parser entry
- * if the latter, we already have a base, just set
- * i to the index of the cfg which members need allocing
- */
- if ((cfp->cf_head->h_cfgs == NULL) ||
- (cfp->cf_head->h_cfgs[n-1].l_entry == NULL)) {
- cfp->cf_head->h_cfgs = (cfglist_t *)calloc(MAX_CFG,
- sizeof (cfglist_t));
- i = 0;
- }
- else
- i = n;
-
- if (cfp->cf_head->h_cfgs) {
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "alloced %d cfg lists \n", n + 1);
-#endif
- for (cfp->cf_head->h_ncfgs = n + 1;
- i < min(cfp->cf_head->h_ncfgs, MAX_CFG); i++) {
- cfp->cf_head->h_cfgs[i].l_name = '\0';
- cfp->cf_head->h_cfgs[i].l_name =
- strdup(chead[i].tag.l_word);
- cfp->cf_head->h_cfgs[i].l_index = i;
- cfp->cf_head->h_cfgs[i].l_entry =
- calloc(DEFAULT_ENTRY_SIZE, sizeof (char));
- cfp->cf_head->h_cfgs[i].l_nentry = 0;
- cfp->cf_head->h_cfgs[i].l_esiz =
- calloc(DEFAULT_NENTRIES, sizeof (int));
- cfp->cf_head->h_cfgs[i].l_size = 0;
- cfp->cf_head->h_cfgs[i].l_free = DEFAULT_ENTRY_SIZE;
- if ((cfp->cf_head->h_cfgs[i].l_entry == NULL) ||
- (cfp->cf_head->h_cfgs[i].l_esiz == NULL)) {
- cfg_perror_str = dgettext("cfg", "unable to"
- " allocate cfglist members");
- cfg_severity = CFG_EFATAL;
- }
- }
- } else {
- cfg_perror_str = dgettext("cfg", "unable to alloc cfglist");
- cfg_severity = CFG_EFATAL;
- }
-}
-
-/*
- * cfg_map_cfglists()
- * go through list of list sizes in header
- * and create separate lists
- */
-int
-cfg_map_cfglists(cfp_t *cfp)
-{
- int i;
- int offset = 0;
- int *ip;
- int list_size = 0;
- int slot_inc;
- char *p;
- cfgheader_t *ch;
-
- ch = cfp->cf_head;
- p = ch->h_cparse;
-
- /* get the first list size */
- ip = ch->h_sizes;
-
- for (i = 0; i < min(ch->h_ncfgs, MAX_CFG); i++) {
- if (ch->h_cfgsizes[i] > 0) {
- if (ch->h_cfgsizes[i] > DEFAULT_ENTRY_SIZE) {
-
- ch->h_cfgs[i].l_entry = (char *)
- realloc(ch->h_cfgs[i].l_entry,
- ch->h_cfgsizes[i] * sizeof (char));
- /* set free to 0, we'll get more when we add */
- ch->h_cfgs[i].l_free = 0;
-
- } else
- ch->h_cfgs[i].l_free -= ch->h_cfgsizes[i];
-
- /* get lists and marry up to each cfgs structure */
-
-
- list_size = *ip;
- ip++;
-
- if (list_size > DEFAULT_NENTRIES) {
- /*
- * we're gonna need more slots
- * we want to alloc on DEFAULT_NENTRIES
- * boundry. ie. always a multiple of it
- * later on, when we add to the list
- * we can see if we need to add by mod'ding
- * l_nentry and DEFAULT_NENTRIES and check for 0
- */
- slot_inc = DEFAULT_NENTRIES -
- (list_size % DEFAULT_NENTRIES);
- if (slot_inc == DEFAULT_NENTRIES)
- slot_inc = 0; /* addcfline reallocs */
-
- ch->h_cfgs[i].l_esiz = (int *)realloc(
- ch->h_cfgs[i].l_esiz,
- (list_size + slot_inc) * sizeof (int));
- }
- memcpy(ch->h_cfgs[i].l_esiz, ip,
- list_size * sizeof (int));
-
- ch->h_cfgs[i].l_nentry = list_size;
-
- ip += list_size;
-
- } else
-
- continue;
-
- if (ch->h_cfgs[i].l_entry != NULL) {
- p = ch->h_cparse + offset;
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "mapping list %d size %d offset %d, addr 0x%x\n",
- i, ch->h_cfgsizes[i], offset, p);
-#endif
- memcpy(ch->h_cfgs[i].l_entry,
- p, ch->h_cfgsizes[i]);
- ch->h_cfgs[i].l_size = ch->h_cfgsizes[i];
- offset += ch->h_cfgsizes[i];
- } else {
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "NULL l_entry\n");
-#endif
- return (-1);
- }
- }
-
-
- return (1);
-
-}
-
-void
-cfg_replace_lists(cfp_t *cfp)
-{
- int i;
- int offset = 0;
- int size_offset = 0;
-
- int section = 0;
- cfgheader_t *cf;
- cfglist_t *cfl;
-
- cf = cfp->cf_head;
-
- if ((cfl = cfp->cf_head->h_cfgs) == NULL)
- return;
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_replace_lists\n");
-#endif
-
- if (cf->h_cparse == cf->h_ccopy1)
- section = 1;
-
- /*
- * check to see if we are using copy1 or 2,
- * grow or shrink the size, fix h_cparse reference
- * in case realloc gave us a funky new address.
- * put stuff in it.
- */
- cf->h_ccopy1 = (char *)
- realloc(cf->h_ccopy1, cf->h_csize * sizeof (char));
- cf->h_ccopy2 = (char *)
- realloc(cf->h_ccopy2, cf->h_csize * sizeof (char));
- if (section == 1) {
- /* we used copy1 */
- cf->h_cparse = cf->h_ccopy1;
- } else
- cf->h_cparse = cf->h_ccopy2;
-
- /*
- * just because, we'll zero out h_csize and recalc
- * after all, this is the number the next guy gets
- */
- cf->h_csize = cf->h_sizes[0] = 0;
- for (i = 0; i < MAX_CFG; i++) {
- /* only as many lists as chead has */
- if (chead[i].tag.l_word[0] == '\0') {
- break;
- }
- if (cfl[i].l_entry && cfl[i].l_entry[0] != '\0') {
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr,
- "copying list %d at %x size %d\n",
- i, cf->h_cparse + offset,
- cfl[i].l_size);
-#endif
- memcpy((cf->h_cparse + offset),
- cfl[i].l_entry, cfl[i].l_size);
- offset += cfl[i].l_size;
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr,
- "cfl[%d].l_nentry %d cfl[%d].l_esiz[%d] %d"
- " size offset %d\n",
- i, cfl[i].l_nentry, i, cfl[i].l_nentry - 1,
- cfl[i].l_esiz[cfl[i].l_nentry - 1], size_offset);
-#endif
- /*
- * first write the number of entries
- * then copy over the array ie.
- * a list with 5 elements would be copied
- * as a 6 element array slot 0 being the
- * number of elements
- */
- cf->h_sizes[size_offset++] = cfl[i].l_nentry;
- memcpy((cf->h_sizes + size_offset), cfl[i].l_esiz,
- cfl[i].l_nentry * sizeof (int));
- size_offset += cfl[i].l_nentry;
- cf->h_sizes[size_offset] = 0;
- }
- cf->h_csize += cfl[i].l_size;
- }
-}
-
-void
-cfg_free_cfglist(cfp_t *cfp)
-{
- int i;
-
- if (!cfp->cf_head || !cfp->cf_head->h_cfgs)
- return;
-
- for (i = 0; cfp->cf_head && i < MAX_CFG; i++) {
- if (cfp->cf_head->h_cfgs[i].l_entry) {
- free(cfp->cf_head->h_cfgs[i].l_entry);
- cfp->cf_head->h_cfgs[i].l_entry = NULL;
- }
-
- if (cfp->cf_head->h_cfgs[i].l_name) {
- free(cfp->cf_head->h_cfgs[i].l_name);
- cfp->cf_head->h_cfgs[i].l_entry = NULL;
- }
-
- if (cfp->cf_head->h_cfgs[i].l_esiz) {
- free(cfp->cf_head->h_cfgs[i].l_esiz);
- cfp->cf_head->h_cfgs[i].l_esiz = NULL;
- }
- }
-
- if (cfp->cf_head) {
- free(cfp->cf_head->h_cfgs);
- cfp->cf_head->h_cfgs = NULL;
- }
-}
-
-void
-cfg_free_parser_tree()
-{
- struct lookup *p = NULL;
- struct lookup *q = NULL;
- int i;
-
- for (i = 0; i < MAX_CFG; i++) {
- if (chead)
- p = chead[i].fld;
- while (p) {
- q = p->l_next;
- if (p) {
- free(p);
- p = NULL;
- }
- p = q;
- }
- }
- bzero(chead, MAX_CFG * sizeof (struct parser));
-}
-
-void
-cfg_close(CFGFILE *cfg)
-{
- cfp_t *cfp;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return;
- }
-
- /* Determine number of files open */
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
-
- (*cfp->cf_pp->close)(cfp);
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "freeing cfglists\n");
-#endif
- cfg_free_cfglist(cfp);
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "freeing cfp->cf_mapped\n");
-#endif
- free(cfp->cf_mapped);
- cfp->cf_mapped = NULL;
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr,
- "freeing copy1, copy2, h_sizes and cf\n");
-#endif
- if (cfp->cf_head) {
- if (cfp->cf_head->h_ccopy1) {
- free(cfp->cf_head->h_ccopy1);
- cfp->cf_head->h_ccopy1 = NULL;
- }
- if (cfp->cf_head->h_ccopy2) {
- free(cfp->cf_head->h_ccopy2);
- cfp->cf_head->h_ccopy2 = NULL;
- }
- if (cfp->cf_head->h_sizes1) {
- free(cfp->cf_head->h_sizes1);
- cfp->cf_head->h_sizes1 = NULL;
- }
- if (cfp->cf_head->h_sizes2) {
- free(cfp->cf_head->h_sizes2);
- cfp->cf_head->h_sizes2 = NULL;
- }
-
- }
- if (cfp->cf_head)
- free(cfp->cf_head);
- }
-
- free(cfg);
- cfg = NULL;
- cfg_free_parser_tree();
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_close\n");
-#endif
-}
-
-
-char *
-cfg_get_resource(CFGFILE *cfg)
-{
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
-
- return (cfg->cf_node);
-}
-
-/*
- * cfg_resource
- * set or clear the cluster node filter for get/put
- */
-
-void
-cfg_resource(CFGFILE *cfg, const char *node)
-{
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return;
- }
-
- if (cfg->cf_node) {
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr,
- "cfg_resource: changing node from %s to %s\n",
- cfg->cf_node, (node?node:"NULL"));
-#endif
- free(cfg->cf_node);
- cfg->cf_node = NULL;
- }
-
- /*
- * just in case someone passes in a non-NULL
- * node, but has no valid value
- */
- if ((node) && (node[0] != '\0')) {
- cfg->cf_node = strdup(node);
- }
-}
-
-/*
- * cfg_open
- * Open the current configuration file
- */
-CFGFILE *
-cfg_open(char *name)
-{
- CFGFILE *cfg;
- cfp_t *cfp;
- int32_t magic;
- long needed;
- int rc;
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_open\n");
-#endif
-
- cfg_severity = 0;
- if ((cfg = (CFGFILE *)calloc(1, sizeof (*cfg))) == NULL) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: malloc failed");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
-
- cfp = &cfg->cf[0];
- if ((name) && strlen(name)) {
-#ifdef DEBUG
- (void) fprintf(stderr, "cfg_open: Using non-standard name\n");
-#endif
- cfp->cf_name = name;
- cfp->cf_pp = (strstr(cfp->cf_name, "/rdsk/") == NULL) ?
- cfg_block_io_provider() : cfg_raw_io_provider();
- } else {
- cfp->cf_name = cfg_location(NULL, CFG_LOC_GET_LOCAL, NULL);
- cfp->cf_pp = cfg_block_io_provider();
-
- /* Handle cfg_open(""), which is an open from boot tools */
- if (name)
- cl_initialized = 1;
- if (cfg_iscluster() > 0) {
- cfp = &cfg->cf[1];
- cfp->cf_name =
- cfg_location(NULL, CFG_LOC_GET_CLUSTER, NULL);
- if (cfp->cf_name) {
- cfp->cf_pp = cfg_raw_io_provider();
- }
- }
- }
-
- /*
- * Open one or two configuration files
- */
- for (cfp = &cfg->cf[0]; cfp->cf_name && (cfp <= &cfg->cf[1]); cfp++) {
- if ((*cfp->cf_pp->open)(cfp, cfp->cf_name) == NULL) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: unable to open configuration location");
- cfg_severity = CFG_EFATAL;
- break;
- }
-
- /* block device smaller than repository? */
- rc = (*cfp->cf_pp->read)(cfp, &magic, sizeof (magic));
- if (rc < sizeof (magic)) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: unable to read configuration header");
- cfg_severity = CFG_EFATAL;
- break;
- }
-
- if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: unable to seek configuration header");
- cfg_severity = CFG_EFATAL;
- break;
- }
-
- /*
- * we can't enforce size rules on an old database
- * so check the magic number before we test for size
- */
- if (magic == CFG_NEW_MAGIC) {
- needed = FBA_NUM(FBA_SIZE(1) - 1 +
- (sizeof (struct cfgheader) + CFG_CONFIG_SIZE));
- } else {
- needed = 0;
- }
-
- if (cfp->cf_size < needed) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: configuration file too small");
- cfg_severity = CFG_EFATAL;
- errno = ENOMEM;
- break;
- }
-
- cfp->cf_mapped = (char *)malloc(CFG_DEFAULT_PARSE_SIZE);
- if (cfp->cf_mapped == NULL) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: malloc failed");
- cfg_severity = CFG_EFATAL;
- break;
- }
-
- bzero(cfp->cf_mapped, CFG_DEFAULT_PARSE_SIZE);
- cfp->cf_lock = -1;
- }
-
- /* Processing errors, take care of one or more cfp pointers */
- if (cfg_severity && (cfp <= &cfg->cf[1])) {
- cfp = &cfg->cf[0];
- if (cfp->cf_fd)
- (*cfp->cf_pp->close)(cfp);
- cfp = &cfg->cf[1];
- if (cfp->cf_fd)
- (*cfp->cf_pp->close)(cfp);
- free(cfg);
- return (NULL);
- }
-
- cfg_lockd = cfg_lockd_init();
-
-
-#ifdef DEBUG_CFGLIST
- (void) fprintf(stderr, "cfg_open ok\n");
-#endif
- return (cfg);
-}
-
-void
-cfg_invalidate_hsizes(int fd, const char *loc)
-{
- int offset;
- int rc = -1;
- int hdrsz;
-
- char buf[2 * CFG_DEFAULT_PSIZE];
-
- hdrsz = sizeof (cfgheader_t) + 512 -
- (sizeof (cfgheader_t) % 512);
-
- offset = hdrsz + CFG_DEFAULT_PARSE_SIZE +
- (CFG_DEFAULT_SSIZE * 2);
-
- if (cfg_shldskip_vtoc(fd, loc) > 0)
- offset += CFG_VTOC_SKIP;
-
- bzero(buf, sizeof (buf));
-
- if (lseek(fd, offset, SEEK_SET) > 0)
- rc = write(fd, buf, sizeof (buf));
- if (rc < 0)
- (void) fprintf(stderr, "cfg: invalidate hsizes failed\n");
-
-}
-
-char *
-cfg_error(int *severity)
-{
- if (severity != NULL)
- *severity = cfg_severity;
- return (cfg_perror_str ? cfg_perror_str : CFG_EGENERIC);
-}
-/*
- * cfg_cfg_isempty
- */
-int
-cfg_cfg_isempty(CFGFILE *cfg)
-{
- cfp_t *cfp;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- cfp = FP_SUN_CLUSTER(cfg);
- if (cfp->cf_head->h_csize == 0)
- return (TRUE);
- else
- return (FALSE);
-}
-
-/*
- * cfg_get_num_entries
- * return the number of entries in a given section of database
- * sndr, ii, ndr_ii...
- */
-int
-cfg_get_num_entries(CFGFILE *cfg, char *section)
-{
- int count = 0;
- int table_offset;
- cfp_t *cfp;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if ((table_offset = cfg_get_parser_offset(section)) < 0) {
- errno = ESRCH;
- return (-1);
- }
-
- /* Determine number of files open */
- for (cfp = &cfg->cf[0]; cfp->cf_fd && (cfp <= &cfg->cf[1]); cfp++)
- count += cfp->cf_head->h_cfgs[table_offset].l_nentry;
-
- return (count);
-}
-
-/*
- * cfg_get_section
- * all etries in a config file section is placed in
- * buf, allocation is done inside
- * freeing buf is responisbility of the caller
- * number of entries in section is returned
- * -1 on failure, errno is set
- */
-int
-cfg_get_section(CFGFILE *cfg, char ***list, const char *section)
-{
- int table_offset;
- int i, count;
- cfglist_t *cfl;
- char *p = NULL;
- char **buf;
- cfp_t *cfp;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- if ((table_offset = cfg_get_parser_offset(section)) < 0) {
- errno = ESRCH;
- return (-1);
- }
-
- /* Determine number of files open */
- count = 0;
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
- if (cfp->cf_head->h_state & CFG_HDR_INVALID) {
- if (!cfg_read(cfp)) {
- cfg_perror_str = dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- }
-
- cfl = &cfp->cf_head->h_cfgs[table_offset];
- if (cfl->l_nentry == 0) /* empty list */
- continue;
-
- if (count == 0)
- buf = (char **)malloc(cfl->l_nentry * sizeof (char *));
- else
- buf = (char **)realloc(buf, (cfl->l_nentry + count) *
- sizeof (char *));
- if (buf == NULL) {
- errno = ENOMEM;
- return (-1);
- } else {
- bzero(&buf[count], cfl->l_nentry * sizeof (char *));
- }
-
- p = cfl->l_entry;
- for (i = 0; i < cfl->l_nentry; i++) {
- if ((buf[i + count] = strdup(p)) == NULL) {
- errno = ENOMEM;
- return (-1);
- }
- p += cfl->l_esiz[i];
- }
- count += cfl->l_nentry;
- }
-
- *list = buf;
- return (count);
-}
-
-/*
- * cluster upgrade helper functions. These support old database operations
- * while upgrading nodes on a cluster.
- */
-
-/*
- * returns the list of configured tags
- * return -1 on error, else the number
- * of tags returned in taglist
- * caller frees
- */
-int
-cfg_get_tags(CFGFILE *cfg, char ***taglist)
-{
- char **list;
- int i = 0;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if (!cfg_rdlock(cfg)) {
- return (-1);
- }
- list = calloc(1, MAX_CFG * sizeof (char *));
- if (list == NULL) {
- errno = ENOMEM;
- return (-1);
- }
-
- while ((i < MAX_CFG) && (chead[i].tag.l_word[0] != '\0')) {
- list[i] = strdup(chead[i].tag.l_word);
- if (list[i] == NULL) {
- for (/* CSTYLE */; i >= 0; i--) {
- if (list[i])
- free(list[i]);
- }
- free(list);
- errno = ENOMEM;
- return (-1);
- }
- i++;
- }
- *taglist = list;
- return (i);
-
-}
-
-/*
- * is this a database?
- * check the header for the magic number
- * 0 no match 1 match, -1 on error
- */
-int
-cfg_is_cfg(CFGFILE *cfg)
-{
- int32_t magic;
- int rc;
- cfp_t *cfp = FP_SUN_CLUSTER(cfg);
-
- rc = (cfp->cf_pp->read)(cfp, &magic, sizeof (magic));
- if (rc < sizeof (magic)) {
- cfg_perror_str = dgettext("cfg", "Fail to read configuration");
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
-
- if (magic == CFG_NEW_MAGIC)
- return (1);
-
- cfg_perror_str = dgettext("cfg",
- "configuration not initialized, bad magic");
- cfg_severity = CFG_EFATAL;
-
- return (0);
-}
-
-int
-compare(const void* a, const void *b)
-{
- char *p;
- char *pbuf;
- char *q;
- char *qbuf;
- int needed;
- int cmp;
- int pos;
-
- pbuf = strdup(a);
- qbuf = strdup(b);
-
- if (!qbuf || !pbuf)
- return (0);
-
- pos = 1;
- needed = sortby.offset;
-
- p = strtok(pbuf, " ");
- while (p) {
- if (needed == pos) {
- break;
- }
- p = strtok(NULL, " ");
- if (!p)
- break;
- pos++;
- }
-
- pos = 1;
- q = strtok(qbuf, " ");
- while (q) {
- if (needed == pos) {
- break;
- }
- q = strtok(NULL, " ");
- if (!q)
- break;
- pos++;
- }
- if (!p || !q) {
- sortby.comperror++;
- free(pbuf);
- free(qbuf);
- return (0);
- }
- cmp = strcmp(p, q);
- free(pbuf);
- free(qbuf);
- return (cmp);
-
-
-}
-/*
- * cfg_get_srtdsec
- * returns the section, sorted by supplied field
- * caller frees mem
- */
-int
-cfg_get_srtdsec(CFGFILE *cfg, char ***list, const char *section,
- const char *field)
-{
- cfglist_t *cfl;
- cfp_t *cfp;
- char **buf;
- char *tmplst;
- char *p, *q;
- int table_offset;
- int count, i;
-
- if (cfg == NULL) {
- cfg_perror_str = dgettext("cfg", CFG_EINVAL);
- cfg_severity = CFG_EFATAL;
- return (FALSE);
- }
-
- if ((table_offset = cfg_get_parser_offset(section)) < 0) {
- cfg_perror_str = dgettext("cfg", CFG_RDFAILED);
- errno = ESRCH;
- return (-1);
- }
-
- /*
- * do essentially what get_section does,
- * except stick entries in a static size
- * buf to make things easier to qsort
- */
- count = 0;
- for (cfp = &cfg->cf[0]; cfp <= &cfg->cf[1]; cfp++) {
- if (!cfp->cf_fd) continue;
- if (cfp->cf_head->h_state & CFG_HDR_INVALID) {
- if (!cfg_read(cfp)) {
- cfg_perror_str = dgettext("cfg", CFG_RDFAILED);
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- }
-
- cfl = &cfp->cf_head->h_cfgs[table_offset];
- if (cfl->l_nentry == 0) /* empty list */
- continue;
-
- if (count == 0)
- buf = (char **)malloc(cfl->l_nentry * sizeof (char *));
- else
- buf = (char **)realloc(buf, (cfl->l_nentry + count) *
- sizeof (char *));
- if (buf == NULL) {
- errno = ENOMEM;
- cfg_perror_str = dgettext("cfg", "cfg_get_srtdsec: "
- "malloc failed");
- cfg_severity = CFG_EFATAL;
- return (-1);
- } else {
- bzero(&buf[count], cfl->l_nentry * sizeof (char *));
- }
-
- /*
- * allocate each line
- */
- for (i = count; i < cfl->l_nentry + count; i++) {
- buf[i] = calloc(1, CFG_MAX_BUF);
- if (buf[i] == NULL) {
- free(buf);
- errno = ENOMEM;
- return (-1);
- }
- }
-
- if (count == 0)
- tmplst = (char *)malloc(cfl->l_nentry * CFG_MAX_BUF);
- else
- tmplst = (char *)realloc(tmplst,
- (cfl->l_nentry + count) * CFG_MAX_BUF);
- if (tmplst == NULL) {
- cfg_perror_str = dgettext("cfg", "cfg_get_srtdsec: "
- "malloc failed");
- cfg_severity = CFG_EFATAL;
- free(buf);
- return (-1);
- } else {
- bzero(&tmplst[count], cfl->l_nentry * CFG_MAX_BUF);
- }
-
- /*
- * put the section in tmplst and sort
- */
- p = &tmplst[count];
- q = cfl->l_entry;
- for (i = 0; i < cfl->l_nentry; i++) {
- bcopy(q, p, cfl->l_esiz[i]);
- p += CFG_MAX_BUF;
- q += cfl->l_esiz[i];
- }
- count += cfl->l_nentry;
- }
-
- bzero(sortby.section, CFG_MAX_KEY);
- bzero(sortby.field, CFG_MAX_KEY);
-
- strcpy(sortby.section, section);
- strcpy(sortby.field, field);
- sortby.comperror = 0;
- sortby.offset = cfg_get_item(&chead[0], section, field);
-
- qsort(tmplst, count, CFG_MAX_BUF, compare);
-
- if (sortby.comperror) {
- sortby.comperror = 0;
- cfg_perror_str = dgettext("cfg", "cfg_get_srtdsec: "
- "comparison error");
- cfg_severity = CFG_ENONFATAL;
- cfg_free_section(&buf, cfl->l_nentry);
- free(tmplst);
- *list = NULL;
- return (-1);
- }
-
- p = tmplst;
- for (i = 0; i < count; i++) {
- bcopy(p, buf[i], CFG_MAX_BUF);
- p += CFG_MAX_BUF;
- }
-
- free(tmplst);
- *list = buf;
- return (count);
-}
-
-/*
- * free an array alloc'd by get_*section
- * or some other array of size size
- */
-
-void
-cfg_free_section(char ***section, int size)
-{
- int i;
- char **secpp = *section;
-
- for (i = 0; i < size; i++) {
- if (secpp[i]) {
- free(secpp[i]);
- secpp[i] = NULL;
- }
- }
- if (secpp) {
- free(secpp);
- secpp = NULL;
- }
- section = NULL;
-}
-
-
-int
-cfg_shldskip_vtoc(int fd, const char *loc)
-{
- struct vtoc vtoc;
- struct stat sb;
- int slice;
- int rfd;
- char char_name[PATH_MAX];
- char *p;
-
- if (fstat(fd, &sb) == -1) {
- cfg_perror_str = dgettext("cfg", "unable to stat config");
- cfg_severity = CFG_EFATAL;
- return (-1);
- }
- if (S_ISREG(sb.st_mode))
- return (0);
-
- if (S_ISCHR(sb.st_mode)) {
- if ((slice = read_vtoc(fd, &vtoc)) < 0)
- return (-1);
-
- if (vtoc.v_part[slice].p_start < CFG_VTOC_SIZE)
- return (1);
- else
- return (0);
- }
-
- if (S_ISBLK(sb.st_mode)) {
- p = strstr(loc, "/dsk/");
- if (p == NULL)
- return (-1);
- strcpy(char_name, loc);
- char_name[strlen(loc) - strlen(p)] = 0;
- strcat(char_name, "/rdsk/");
- strcat(char_name, p + 5);
-
- if ((rfd = open(char_name, O_RDONLY)) < 0) {
- return (-1);
- }
- if ((slice = read_vtoc(rfd, &vtoc)) < 0) {
- close(rfd);
- return (-1);
- }
- close(rfd);
- if (vtoc.v_part[slice].p_start < CFG_VTOC_SIZE)
- return (1);
- else
- return (0);
- }
-
- return (-1);
-}
-
-/*
- * comapares incore header with one on disk
- * returns 0 if equal, 1 if not, -1 error
- */
-int
-cfg_hdrcmp(cfp_t *cfp)
-{
- cfgheader_t *dskhdr, *memhdr;
- int rc;
-
- if ((dskhdr = calloc(1, sizeof (*dskhdr))) == NULL) {
- cfg_perror_str = dgettext("cfg", "cfg_hdrcmp: No memory");
- cfg_severity = CFG_ENONFATAL;
- }
-
- if ((*cfp->cf_pp->seek)(cfp, 0, SEEK_SET) < 0) {
- cfg_perror_str = dgettext("cfg", "cfg_hdrcmp: seek failed");
- cfg_severity = CFG_ENONFATAL;
- free(dskhdr);
- return (-1);
- }
-
- rc = (*cfp->cf_pp->read)(cfp, (char *)dskhdr, sizeof (*dskhdr));
- if (rc < 0) {
- cfg_perror_str = dgettext("cfg", "cfg_hdrcmp: read failed");
- cfg_severity = CFG_ENONFATAL;
- free(dskhdr);
- return (-1);
- }
-
- memhdr = cfp->cf_head;
-
- if ((memhdr->h_seq1 == dskhdr->h_seq1) &&
- (memhdr->h_seq2 == dskhdr->h_seq2))
- rc = 0;
- else
- rc = 1;
-
-
- free(dskhdr);
- return (rc);
-}
diff --git a/usr/src/lib/libdscfg/common/cfg.h b/usr/src/lib/libdscfg/common/cfg.h
deleted file mode 100644
index 84e64b8ebe..0000000000
--- a/usr/src/lib/libdscfg/common/cfg.h
+++ /dev/null
@@ -1,180 +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 _CFG_H
-#define _CFG_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <sys/nsctl/nsctl.h>
-
-#define CFG_MAX_BUF 1024 /* maximum buffer size for cfg_get_?string() */
-#define CFG_MAX_KEY 256 /* maximum key size for cfg_get_?string() */
-
-#ifndef _CFG_IMPL_H
-/*
- * These are really declared in cfg_impl.h, declare as dummy's here to
- * allow clients to compile without including cfg_impl.h.
- */
-typedef struct cfgfile CFGFILE;
-typedef struct cfp cfp_t;
-
-#endif /* _CFG_IMPL_H */
-
-int cfg_get_cstring(CFGFILE *cfg, const char *key, void *value, int value_len);
-int cfg_put_cstring(CFGFILE *cfg, const char *key, void *value, int value_len);
-int cfg_find_cstring(CFGFILE *cfg, const char *target, const char *section,
- int numflds, ...);
-int cfg_get_options(CFGFILE *cfg, int section, const char *basekey,
- char *tag, int tag_len, char *val, int val_len);
-int cfg_put_options(CFGFILE *cfg, int section, const char *basekey,
- char *tag, char *val);
-int cfg_get_single_option(CFGFILE *, int, const char *, char *, char *, int);
-int cfg_del_option(CFGFILE *, int, const char *, char *);
-
-int cfg_get_num_entries(CFGFILE *cfg, char *section);
-
-int cfg_get_tags(CFGFILE *cfg, char ***taglist);
-
-int cfg_cfg_isempty(CFGFILE *cfg);
-int cfg_get_section(CFGFILE *cfg, char ***buf, const char *section);
-CFGFILE *cfg_open(char *filename);
-void cfg_rewind(CFGFILE *cfg, int section);
-int cfg_is_cfg(CFGFILE *cfg);
-int cfg_shldskip_vtoc(int fd, const char *loc);
-int cfg_get_srtdsec(CFGFILE *cfg, char ***list,
- const char *sec, const char *field);
-void cfg_free_section(char ***, int);
-
-
-/*
- * Handle cluster configuration
- */
-#define FP_SUN_CLUSTER(x) \
- (((x->cf_node) && (x->cf[1].cf_fd)) ? &x->cf[1] : &x->cf[0])
-
-/*
- * rewind sections
- */
-#define CFG_SEC_CONF 0 /* configuration section */
-#define CFG_SEC_PERS 1 /* persistent section */
-#define CFG_SEC_ALL 2 /* rewind both sections */
-
-int cfg_update_parser_config(CFGFILE *, const char *key, int section);
-/*
- * parser sections
- */
-#define CFG_PARSE_CONF 0 /* config section key */
-#define CFG_PARSE_PERS 1 /* persistent section key */
-
-char *cfg_error(int *severity);
-/*
- * error codes
- */
-#define CFG_ENONFATAL 0 /* non fatal error */
-#define CFG_EFATAL 1 /* fatal error exit */
-
-/*
- * some error strings
- */
-#define CFG_NOTLOCKED "Configuration not locked"
-#define CFG_RDFAILED "Unable to read configuration"
-#define CFG_EINVAL "Invalid Argument"
-#define CFG_EGENERIC "Generic cfg failure"
-
-
-char *cfg_location(char *location, int mode, char *altroot);
-
-/*
- * location modes
- */
-#define CFG_LOC_SET_LOCAL 0
-#define CFG_LOC_GET_LOCAL 1
-#define CFG_LOC_SET_CLUSTER 2
-#define CFG_LOC_GET_CLUSTER 3
-
-/*
- * location strings
- */
-#define CFG_LOCAL_LOCATION "/etc/dscfg_local"
-#define CFG_CLUSTER_LOCATION "/etc/dscfg_cluster"
-
-void cfg_close(CFGFILE *);
-
-/*
- * lock mode
- */
-typedef enum {
- CFG_RDLOCK,
- CFG_WRLOCK,
- CFG_UPGRADE
-} CFGLOCK;
-
-int cfg_lock(CFGFILE *, CFGLOCK); /* lock the configuration */
-void cfp_unlock(cfp_t *); /* unlock the configuration */
-void cfg_unlock(CFGFILE *);
-int cfg_get_lock(CFGFILE *, CFGLOCK *, pid_t *); /* get config lock */
-
-int cfg_commit(CFGFILE *);
-void cfg_resource(CFGFILE *, const char *); /* Set/clear cluster node */
-char *cfg_get_resource(CFGFILE *); /* get current cluster node */
-char *cfg_dgname(const char *, char *, size_t); /* parse dg from pathname */
-char *cfg_l_dgname(const char *, char *, size_t); /* parse dg from pathname */
-int cfg_dgname_islocal(char *, char **); /* find locality of dg */
-int cfg_iscluster(void); /* running in a cluster? */
-int cfg_issuncluster(void); /* running in a Sun Cluster? */
-void cfg_invalidate_sizes(int);
-
-/*
- * add/rem result codes
- */
-#define CFG_USER_ERR 1
-#define CFG_USER_OK 2
-#define CFG_USER_FIRST 3
-#define CFG_USER_LAST 4
-#define CFG_USER_GONE 5
-#define CFG_USER_REPEAT 6
-
-int cfg_add_user(CFGFILE *, char *, char *, char *); /* add volume user */
-int cfg_rem_user(CFGFILE *, char *, char *, char *); /* remove vol user */
-int cfg_vol_enable(CFGFILE *, char *, char *, char *); /* enable volume */
-int cfg_vol_disable(CFGFILE *, char *, char *, char *); /* disable volume */
-
-int cfg_load_dsvols(CFGFILE *); /* load dsvol: section */
-void cfg_unload_dsvols(); /* unload dsvol: section */
-int cfg_load_svols(CFGFILE *); /* load sv: section */
-void cfg_unload_svols(); /* unload sv: section */
-int cfg_load_shadows(CFGFILE *); /* load shadows & bitmaps from ii: */
-void cfg_unload_shadows(); /* unload ii: */
-
-int cfg_get_canonical_name(CFGFILE *, const char *, char **);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CFG_H */
diff --git a/usr/src/lib/libdscfg/common/cfg_cluster.c b/usr/src/lib/libdscfg/common/cfg_cluster.c
deleted file mode 100644
index c94b12c91e..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_cluster.c
+++ /dev/null
@@ -1,582 +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.
- */
-
-/*
- * This file contains the glue code that allows the NWS software to
- * determine whether a cluster disk service is local to this node or
- * not.
- *
- * See PSARC/1999/462 for more information on the interfaces from
- * suncluster that are used here.
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/mkdev.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <strings.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <dlfcn.h>
-
-#include <sys/ncall/ncall.h>
-#include <sys/nsctl/nsc_hash.h>
-
-#include "cfg_cluster.h"
-#include "cfg_impl.h"
-#include "cfg.h"
-
-/*
- * Static variables
- */
-
-static scconf_nodeid_t cl_nodeid = (uint_t)0xffff;
-static char *cl_nodename = NULL;
-
-static void *libscstat;
-static void *libscconf;
-
-static hash_node_t **schash;
-static int init_sc_entry();
-
-typedef struct hash_data_s {
- scstat_node_name_t scstat_node_name;
-} hash_data_t;
-
-/*
- * Global variables
- */
-int cl_initialized = 0;
-
-
-/*
- * Tell the linker to keep quiet.
- */
-
-#pragma weak scconf_get_nodename
-#pragma weak scconf_strerr
-#pragma weak scconf_get_ds_by_devt
-
-#pragma weak scstat_get_ds_status
-#pragma weak scstat_free_ds_status
-#pragma weak scstat_strerr
-
-
-/*
- * Initialise the library if we have not done so before.
- *
- * - IMPORTANT -
- *
- * This must -never- be called from any command that can be started
- * from /usr/cluster/lib/sc/run_reserve (and hence
- * /usr/cluster/sbin/reconfig) or the system will deadlock
- * during switchover. This includes:
- *
- * - svadm (no options, "print") -- called during sv switchover
- * - all boot commands
- *
- * - grab this node's cluster nodeid
- * - attempt to dlopen() the suncluster shared libraries we need
- * - grab this node's cluster nodename
- *
- * Returns:
- * 0 - success
- * -1 - error, errno is set
- */
-
-int
-cfg_cluster_init(void)
-{
- const char *scconf = "/usr/cluster/lib/libscconf.so.1";
- const char *scstat = "/usr/cluster/lib/libscstat.so.1";
-#ifdef DEBUG
- char errbuf[SCCONF_MAXSTRINGLEN];
-#endif
- scconf_nodeid_t id;
- scconf_errno_t err;
- char *name;
- FILE *pipe;
- int rc;
-
- /*
- * First check to see if we really are a cluster as clinfo -n can lie
- */
- if (cl_nodeid == 0xffff) {
- rc = system("/usr/sbin/clinfo");
- if (rc != -1 && WEXITSTATUS(rc) == 1) {
- /* not a cluster */
- cl_initialized = 1;
- cl_nodeid = 0;
- return (0);
- }
-
- pipe = popen("/usr/sbin/clinfo -n 2>/dev/null || echo 0", "r");
- if (pipe == NULL) {
-#ifdef DEBUG
- fprintf(stderr, "unable to get nodeid: %s\n",
- strerror(errno));
-#endif
- return (-1);
- }
-
- if ((rc = fscanf(pipe, "%d", &id)) != 1) {
-#ifdef DEBUG
- fprintf(stderr, "unable to get nodeid: %s\n",
- strerror(errno));
-#endif
- return (-1);
- }
-
- pclose(pipe);
-
- cl_nodeid = id;
- }
-
- /* Already loaded the Sun Cluster device tree */
- if (cl_initialized)
- return (0);
-
- /*
- * Try and dlopen the various libraries that we need
- */
-
- libscconf = dlopen(scconf, RTLD_LAZY | RTLD_GLOBAL);
- if (libscconf == NULL)
- goto error;
-
- libscstat = dlopen(scstat, RTLD_LAZY | RTLD_GLOBAL);
- if (libscstat == NULL)
- goto error;
-
- err = scconf_get_nodename(id, &name);
- if (err == SCCONF_EPERM) {
- cl_nodename = NULL;
- } else if (err != SCCONF_NOERR) {
-#ifdef DEBUG
- scconf_strerr(errbuf, err);
- fprintf(stderr, "scconf_get_nodename: %d: %s\n", err, errbuf);
-#endif
- goto error;
- } else
- cl_nodename = name;
-
- /* Load the Sun Cluster device tree */
- init_sc_entry();
- cl_initialized = 1;
- return (0);
-
-error: /* error cleanup */
- if (libscconf)
- dlclose(libscconf);
-
- if (libscstat)
- dlclose(libscstat);
-
- libscconf = NULL;
- libscstat = NULL;
-
- errno = ENOSYS;
- return (-1);
-}
-
-
-/*
- * cfg_issuncluster()
- *
- * Description:
- * Return the SunCluster nodeid of this node.
- *
- * Returns:
- * >0 - running in a SunCluster (value is nodeid of this node)
- * 0 - not running in a cluster
- * -1 - failure; errno is set
- */
-
-int
-cfg_issuncluster()
-{
- if (cfg_cluster_init() >= 0)
- return ((int)cl_nodeid);
- else
- return (-1);
-}
-int
-cfg_iscluster()
-{
- return (cfg_issuncluster());
-}
-
-/*
- * cfg_l_dgname_islocal()
- * Check if disk group is local on a non-SunCluster.
- *
- * Returns as cfg_dgname_islocal().
- */
-#ifndef lint
-static int
-cfg_l_dgname_islocal(char *dgname, char **othernode)
-{
- const char *metaset = "/usr/sbin/metaset -s %s -o > /dev/null 2>&1";
- char command[1024];
- int rc;
-
- if (snprintf(command, sizeof (command), metaset, dgname) >=
- sizeof (command)) {
- errno = ENOMEM;
- return (-1);
- }
-
- rc = system(command);
- if (rc < 0) {
- return (-1);
- }
-
- if (WEXITSTATUS(rc) != 0) {
- if (othernode) {
- /* metaset doesn't tell us */
- *othernode = "unknown";
- }
-
- return (0);
- }
-
- return (1);
-}
-#endif
-
-/*
- * cfg_dgname_islocal(char *dgname, char **othernode)
- * -- determine if the named disk service is mastered on this node
- *
- * If the disk service is mastered on another node, that nodename
- * will be returned in othernode (if not NULL). It is up to the
- * calling program to call free() on this value at a later time to
- * free the memory allocated.
- *
- * Returns:
- * 1 - disk service is mastered on this node
- * 0 - disk service is not mastered on this node (*othernode set)
- * -1 - error (errno will be set)
- */
-
-int
-cfg_dgname_islocal(char *dgname, char **othernode)
-{
- hash_data_t *data;
-
- if (dgname == NULL || *dgname == '\0' || othernode == NULL) {
- errno = EINVAL;
- return (-1);
- }
-
- /* Handle non-cluster configurations */
- if (cfg_cluster_init() < 0) {
- return (-1);
- } else if (cl_nodeid == 0) {
- /* it has to be local */
- return (1);
- }
-
- /*
- * lookup the current diskgroup name
- */
- if (data = (hash_data_t *)nsc_lookup(schash, dgname)) {
- if (strcmp(data->scstat_node_name, cl_nodename)) {
- if (othernode)
- *othernode = strdup(data->scstat_node_name);
- return (0);
- } else {
- return (1);
- }
- } else {
- errno = ENODEV;
- return (-1);
- }
-}
-
-/*
- * cfg_l_dgname()
- * parse the disk group name from the a device pathname on a non-SunCluster.
- *
- * Returns as cfg_dgname().
- */
-
-char *
-cfg_l_dgname(const char *pathname, char *buffer, size_t buflen)
-{
- const char *dev = "/dev/";
- const char *vx = "vx/";
- const char *md = "md/";
- const char *dsk = "dsk/";
- const char *start, *cp;
- int ll, len, chkdsk;
-
- bzero(buffer, buflen);
- chkdsk = 0;
-
- ll = strlen(dev);
- if (strncmp(pathname, dev, ll) != 0) {
- /* not a device pathname */
- errno = EINVAL;
- return ((char *)NULL);
- }
-
- start = pathname + ll;
-
- if (strncmp(start, vx, (ll = strlen(vx))) == 0) {
- /*
- * Veritas --
- * /dev/vx/{r}dsk/dgname/partition
- */
-
- start += ll;
-
- ll = strlen(dsk);
-
- if (*start == 'r' && strncmp((start + 1), dsk, ll) == 0)
- start += ll + 1;
- else if (strncmp(start, dsk, ll) == 0)
- start += ll;
- else {
- /* no dgname */
- return (buffer);
- }
- } else {
- /* no dgname */
- return (buffer);
- }
-
- for (cp = start, len = 0; *cp != '\0' && *cp != '/'; cp++)
- len++; /* count length of dgname */
-
- if (*cp == '\0') {
- /* no dgname */
- return (buffer);
- }
-
-#ifdef DEBUG
- if (*cp != '/') {
- fprintf(stderr,
- "cfg_dgname: parse error: *cp = '%c', expected '/'\n", *cp);
- errno = EPROTO;
- return ((char *)NULL);
- }
-#endif
-
- if (chkdsk) {
- cp++; /* skip the NULL */
-
- ll = strlen(dsk);
-
- if ((*cp != 'r' || strncmp((cp + 1), dsk, ll) != 0) &&
- strncmp(cp, dsk, ll) != 0) {
- /* no dgname */
- return (buffer);
- }
- }
-
- if (len >= buflen) {
- errno = E2BIG;
- return ((char *)NULL);
- }
-
- (void) strncpy(buffer, start, len);
- return (buffer);
-}
-
-
-/*
- * cfg_dgname()
- * determine which cluster resource group the pathname belongs to, if any
- *
- * Returns:
- * NULL - error (errno is set)
- * ptr to NULL-string - no dgname
- * pointer to string - dgname
- */
-
-char *
-cfg_dgname(const char *pathname, char *buffer, size_t buflen)
-{
- scconf_errno_t conferr;
- char *dsname = NULL;
- struct stat stb;
-#ifdef DEBUG
- char errbuf[SCCONF_MAXSTRINGLEN];
-#endif
-
- bzero(buffer, buflen);
-
- if (pathname == NULL || *pathname == '\0') {
- errno = EINVAL;
- return ((char *)NULL);
- }
-
- /* Handle non-cluster configurations */
- if (cfg_cluster_init() < 0) {
- errno = EINVAL;
- return ((char *)NULL);
- } else if (cl_nodeid == 0) {
- /* must be local - return NULL-string dgname */
- return (buffer);
- }
-
- if (stat(pathname, &stb) < 0) {
- errno = EINVAL;
- return ((char *)NULL);
- }
-
- conferr = scconf_get_ds_by_devt(major(stb.st_rdev),
- minor(stb.st_rdev), &dsname);
-
- if (conferr == SCCONF_ENOEXIST) {
- return (buffer);
- } else if (conferr != SCCONF_NOERR) {
-#ifdef DEBUG
- scconf_strerr(errbuf, conferr);
- fprintf(stderr,
- "scconf_get_ds_by_devt: %d: %s\n", conferr, errbuf);
-#endif
- errno = EINVAL;
- return ((char *)NULL);
- }
-
- strncpy(buffer, dsname, buflen);
- free(dsname);
-
- return (buffer);
-}
-
-
-/*
- * init_sc_entry
- *
- * Add an entry into the sclist and the schash for future lookups.
- *
- * - IMPORTANT -
- *
- * This must -never- be called from any command that can be started
- * from /usr/cluster/lib/sc/run_reserve (and hence
- * /usr/cluster/sbin/reconfig) or the system will deadlock
- * during switchover. This includes:
- *
- * - svadm (no options, "print") -- called during sv switchover
- * - all boot commands
- *
- * Return values:
- * -1 An error occurred.
- * 0 Entry added
- * 1 Entry already exists.
- */
-static int
-init_sc_entry()
-{
- scstat_ds_node_state_t *dsn;
- scstat_ds_name_t dsname;
- scstat_ds_t *dsstatus, *dsp;
- scstat_errno_t err;
-#ifdef DEBUG
- char errbuf[SCCONF_MAXSTRINGLEN];
-#endif
-
- hash_data_t *hdp;
-
- /*
- * Allocate a hash table
- */
- if ((schash = nsc_create_hash()) == NULL)
- return (-1);
-
- /*
- * the API is broken here - the function is written to expect
- * the first argument to be (scstat_ds_name_t), but the function
- * declaration in scstat.h requires (scstat_ds_name_t *).
- *
- * We just cast it to get rid of the compiler warnings.
- * If "dsname" is NULL, information for all device services is returned
- */
- dsstatus = NULL;
- dsname = NULL;
- /* LINTED pointer alignment */
- err = scstat_get_ds_status((scstat_ds_name_t *)dsname, &dsstatus);
- if (err != SCSTAT_ENOERR) {
-#ifdef DEBUG
- scstat_strerr(err, errbuf);
- fprintf(stderr, "scstat_get_ds_status(): %d: %s\n",
- err, errbuf);
-#endif
- errno = ENOSYS;
- return (-1);
- }
-
- if (dsstatus == NULL) {
- errno = ENODEV;
- return (-1);
- }
-
- /*
- * Traverse scstat_ds list, saving away resource in out hash table
- */
- for (dsp = dsstatus; dsp; dsp = dsp->scstat_ds_next) {
-
- /* Skip over NULL scstat_ds_name's */
- if ((dsp->scstat_ds_name == NULL) ||
- (dsp->scstat_ds_name[0] == '\0'))
- continue;
-
- /* See element exits already, error if so */
- if (nsc_lookup(schash, dsp->scstat_ds_name)) {
- fprintf(stderr, "scstat_get_ds_status: duplicate %s",
- dsp->scstat_ds_name);
- errno = EEXIST;
- return (-1);
- }
-
- /* Traverse the node status list */
- for (dsn = dsp->scstat_node_state_list; dsn;
- dsn = dsn->scstat_node_next) {
- /*
- * Only keep trace of primary nodes
- */
- if (dsn->scstat_node_state != SCSTAT_PRIMARY)
- continue;
-
- /* Create an element to insert */
- hdp = (hash_data_t *)malloc(sizeof (hash_data_t));
- hdp->scstat_node_name = strdup(dsn->scstat_node_name);
- nsc_insert_node(schash, hdp, dsp->scstat_ds_name);
- }
- }
-
- /*
- * Free up scstat resources
- */
- scstat_free_ds_status(dsstatus);
- return (0);
-}
diff --git a/usr/src/lib/libdscfg/common/cfg_cluster.h b/usr/src/lib/libdscfg/common/cfg_cluster.h
deleted file mode 100644
index 56f07219f7..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_cluster.h
+++ /dev/null
@@ -1,344 +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 _CFG_CLUSTER_H
-#define _CFG_CLUSTER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * This file is a combination of interfaces culled from scstat.h,
- * scconf.h and the header files that they include.
- *
- * It exposes a subset of the interfaces defined in PSARC/2001/261
- * for use in NWS software.
- */
-
-#include <sys/errno.h>
-#include <sys/types.h>
-
-/*
- * From sc_syslog_msg.h
- */
-
-typedef enum sc_state_code_enum {
- ONLINE = 1, /* resource is running */
- OFFLINE, /* resource is stopped due to user action */
- FAULTED, /* resource is stopped due to a failure */
- DEGRADED, /* resource is running but has a minor problem */
- WAIT, /* resource is in transition from a state to another */
-
- /*
- * resource is monitored but state of the resource is
- * not known because either the monitor went down or
- * the monitor cannot report resource state temporarily.
- */
- UNKNOWN,
-
- NOT_MONITORED /* There is no monitor to check state of the resource */
-} sc_state_code_t;
-
-/*
- * End sc_syslog_msg.h
- */
-
-
-/*
- * From scstat.h
- */
-
-#define SCSTAT_MAX_STRING_LEN 1024
-
-/* Error codes returned by scstat functions. */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef enum scstat_errno {
- SCSTAT_ENOERR, /* normal return - no error */
- SCSTAT_EUSAGE, /* syntax error */
- SCSTAT_ENOMEM, /* not enough memory */
- SCSTAT_ENOTCLUSTER, /* not a cluster node */
- SCSTAT_ENOTCONFIGURED, /* not found in CCR */
- SCSTAT_ESERVICENAME, /* dcs: invalid service name */
- SCSTAT_EINVAL, /* scconf: invalid argument */
- SCSTAT_EPERM, /* not root */
- SCSTAT_ECLUSTERRECONFIG, /* cluster is reconfiguring */
- SCSTAT_ERGRECONFIG, /* RG is reconfiguring */
- SCSTAT_EOBSOLETE, /* Resource/RG has been updated */
- SCSTAT_EUNEXPECTED /* internal or unexpected error */
-} scstat_errno_t;
-
-/* States a resource can be in */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef enum scstat_state_code {
- SCSTAT_ONLINE = ONLINE, /* resource is running */
- SCSTAT_OFFLINE = OFFLINE, /* resource stopped due to user action */
- SCSTAT_FAULTED = FAULTED, /* resource stopped due to a failure */
- SCSTAT_DEGRADED = DEGRADED, /* resource running with a minor problem */
- SCSTAT_WAIT = WAIT, /* resource is in transition */
- SCSTAT_UNKNOWN = UNKNOWN, /* resource state is unknown */
- SCSTAT_NOTMONITORED = NOT_MONITORED /* resource is not monitored */
-} scstat_state_code_t;
-
-/* States a replica of a resource can be in */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef enum scstat_node_pref {
- SCSTAT_PRIMARY, /* replica is a primary */
- SCSTAT_SECONDARY, /* replica is a secondary */
- SCSTAT_SPARE, /* replica is a spare */
- SCSTAT_INACTIVE, /* replica is inactive */
- SCSTAT_TRANSITION, /* replica is changing state */
- SCSTAT_INVALID /* replica is in an invalid state */
-} scstat_node_pref_t;
-
-/* component name */
-typedef char *scstat_name_t;
-typedef scstat_name_t scstat_cluster_name_t; /* cluster name */
-typedef scstat_name_t scstat_node_name_t; /* node name */
-typedef scstat_name_t scstat_adapter_name_t; /* adapter name */
-typedef scstat_name_t scstat_path_name_t; /* path name */
-typedef scstat_name_t scstat_ds_name_t; /* device service name */
-typedef scstat_name_t scstat_quorumdev_name_t; /* quorum device name */
-typedef scstat_name_t scstat_rs_name_t; /* resource name */
-typedef scstat_name_t scstat_rg_name_t; /* rg name */
-
-/* status string */
-typedef char *scstat_statstr_t;
-typedef scstat_statstr_t scstat_node_statstr_t; /* node status */
-typedef scstat_statstr_t scstat_path_statstr_t; /* path status */
-typedef scstat_statstr_t scstat_ds_statstr_t; /* DS status */
-typedef scstat_statstr_t scstat_node_quorum_statstr_t; /* node quorum status */
-typedef scstat_statstr_t scstat_quorumdev_statstr_t; /* quorum device stat */
-
-/* ha device node status list */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef struct scstat_ds_node_state_struct {
- /* node name */
- scstat_node_name_t scstat_node_name;
- /* node status */
- scstat_node_pref_t scstat_node_state;
- /* next */
- struct scstat_ds_node_state_struct *scstat_node_next;
-} scstat_ds_node_state_t;
-
-/* Cluster node status */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef struct scstat_node_struct {
- scstat_node_name_t scstat_node_name; /* node name */
- scstat_state_code_t scstat_node_status; /* cluster membership */
- scstat_node_statstr_t scstat_node_statstr; /* node status string */
- void *pad; /* Padding for */
- /* PSARC/2001/261. */
- struct scstat_node_struct *scstat_node_next; /* next */
-} scstat_node_t;
-
-/* Cluster ha device status */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef struct scstat_ds_struct {
- /* ha device name */
- scstat_ds_name_t scstat_ds_name;
- /* ha device status */
- scstat_state_code_t scstat_ds_status;
- /* ha device statstr */
- scstat_ds_statstr_t scstat_ds_statstr;
- /* node preference list */
- scstat_ds_node_state_t *scstat_node_state_list;
- /* next */
- struct scstat_ds_struct *scstat_ds_next;
-} scstat_ds_t;
-
-/*
- * scstat_strerr
- *
- * Map scstat_errno_t to a string.
- *
- * The supplied "errbuffer" should be of at least SCSTAT_MAX_STRING_LEN
- * in length.
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-void scstat_strerr(scstat_errno_t, char *);
-
-/*
- * Upon success, a list of objects of scstat_node_t are returned.
- * The caller is responsible for freeing the space.
- *
- * Possible return values:
- *
- * SCSTAT_NOERR - success
- * SCSTAT_ENOMEM - not enough memory
- * SCSTAT_EPERM - not root
- * SCSTAT_ENOTCLUSTER - there is no cluster
- * SCCONF_EINVAL - invalid argument
- * SCSTAT_EUNEXPECTED - internal or unexpected error
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-scstat_errno_t scstat_get_nodes(scstat_node_t **pplnodes);
-
-/*
- * Free all memory associated with a scstat_node_t structure.
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-void scstat_free_nodes(scstat_node_t *plnodes);
-
-/*
- * If the device service name passed in is NULL, then this function returns
- * the status of all device services, otherwise it returns the status of the
- * device service specified.
- * The caller is responsible for freeing the space.
- *
- * Possible return values:
- *
- * SCSTAT_ENOERR - success
- * SCSTAT_ENOMEM - not enough memory
- * SCSTAT_EPERM - not root
- * SCSTAT_ENOTCLUSTER - there is no cluster
- * SCCONF_EINVAL - invalid argument
- * SCSTAT_ESERVICENAME - invalid device group name
- * SCSTAT_EUNEXPECTED - internal or unexpected error
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-scstat_errno_t scstat_get_ds_status(scstat_ds_name_t *dsname,
- scstat_ds_t **dsstatus);
-
-/*
- * Free memory associated with a scstat_ds_t structure.
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-void scstat_free_ds_status(scstat_ds_t *dsstatus);
-
-/*
- * End scstat.h
- */
-
-/*
- * From scconf.h
- */
-
-/* Maximum message string length */
-#define SCCONF_MAXSTRINGLEN 1024
-
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef enum scconf_errno {
- SCCONF_NOERR = 0, /* normal return - no error */
- SCCONF_EPERM = 1, /* permission denied */
- SCCONF_EEXIST = 2, /* object already exists */
- SCCONF_ENOEXIST = 3, /* object does not exist */
- SCCONF_ESTALE = 4, /* object or handle is stale */
- SCCONF_EUNKNOWN = 5, /* unkown type */
- SCCONF_ENOCLUSTER = 6, /* cluster does not exist */
- SCCONF_ENODEID = 7, /* ID used in place of node name */
- SCCONF_EINVAL = 8, /* invalid argument */
- SCCONF_EUSAGE = 9, /* command usage error */
- SCCONF_ETIMEDOUT = 10, /* call timed out */
- SCCONF_EINUSE = 11, /* already in use */
- SCCONF_EBUSY = 12, /* busy, try again later */
- SCCONF_EINSTALLMODE = 13, /* install mode */
- SCCONF_ENOMEM = 14, /* not enough memory */
- SCCONF_ESETUP = 15, /* setup attempt failed */
- SCCONF_EUNEXPECTED = 16, /* internal or unexpected error */
- SCCONF_EBADVALUE = 17, /* bad ccr table value */
- SCCONF_EOVERFLOW = 18, /* message buffer overflow */
- SCCONF_EQUORUM = 19, /* operation would compromise quorum */
- SCCONF_TM_EBADOPTS = 20, /* bad transport TM "options" */
- SCCONF_TM_EINVAL = 21, /* other transport TM error */
- SCCONF_DS_ESUSPENDED = 22, /* Device service in suspended state */
- SCCONF_DS_ENODEINVAL = 23, /* Node specified is not in cluster */
- SCCONF_EAUTH = 24, /* authentication error */
- SCCONF_DS_EINVAL = 25, /* Device service in an invalid state */
- SCCONF_EIO = 26 /* IO error */
-} scconf_errno_t;
-
-/* IDs */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef uint_t scconf_id_t;
-
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef scconf_id_t scconf_nodeid_t; /* node ID */
-
-/* Cluster transport handle */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-typedef void * scconf_cltr_handle_t;
-
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-extern scconf_errno_t scconf_get_nodeid(char *nodename,
- scconf_nodeid_t *nodeidp);
-
-/*
- * Get the name of a node from its "nodeid". Upon success,
- * a pointer to the nodename is left in "nodenamep".
- *
- * It is the caller's responsibility to free memory allocated
- * for "nodename" using free(3C).
- *
- * Possible return values:
- *
- * SCCONF_NOERR - success
- * SCCONF_EPERM - not root
- * SCCONF_ENOCLUSTER - there is no cluster
- * SCCONF_ENOMEM - not enough memory
- * SCCONF_EINVAL - invalid argument
- * SCCONF_EUNEXPECTED - internal or unexpected error
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-extern scconf_errno_t scconf_get_nodename(scconf_nodeid_t nodeid,
- char **nodenamep);
-
-/*
- * Map scconf_errno_t to a string.
- *
- * The supplied "errbuffer" should be of at least SCCONF_MAXSTRINGLEN
- * in length.
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-extern void scconf_strerr(char *errbuffer, scconf_errno_t err);
-
-/*
- * Given a dev_t value, return the name of device service that contains this
- * device.
- *
- * The caller is responsible for freeing the memory returned in "name".
- *
- * Possible return values:
- *
- * SCCONF_NOERR - success
- * SCCONF_EPERM - not root
- * SCCONF_ENOEXIST - the given device is not configured
- * SCCONF_ENOMEM - not enough memory
- * SCCONF_ENOCLUSTER - cluster config does not exist
- * SCCONF_EUNEXPECTED - internal or unexpected error
- */
-/* This definition is covered by PSARC/2001/261. DO NOT change it. */
-extern scconf_errno_t scconf_get_ds_by_devt(major_t maj, minor_t min,
- char **dsname);
-
-/*
- * End scconf.h
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CFG_CLUSTER_H */
diff --git a/usr/src/lib/libdscfg/common/cfg_impl.h b/usr/src/lib/libdscfg/common/cfg_impl.h
deleted file mode 100644
index a972b2525f..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_impl.h
+++ /dev/null
@@ -1,247 +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 _CFG_IMPL_H
-#define _CFG_IMPL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MAX_CFG 16 /* Max. number of lines in /etc/dscfg_format */
-
-#define CFG_MAX_KEY 256
-#define CFG_MAX_BUF 1024
-#define CFG_BLOCK_SIZE 512
-#define CFG_VTOC_SIZE 16
-#define CFG_VTOC_SKIP CFG_VTOC_SIZE * CFG_BLOCK_SIZE
-
-/*
- * Parser and file handling routines for Configuration parser.
- *
- * General layout on disk
- *
- * header cfgheader_t
- * parser configuration tag.field1.field2\n
- * configuration data copy1 freeform strings
- * configuration data copy2 freeform strings
- *
- * Strings in freeform fields are seperated by whitespace.
- * End of entry seperated by null.
- */
-
-struct lookup {
- char l_word[CFG_MAX_KEY];
- int l_value;
- struct lookup *l_next;
-};
-
-struct parser {
- struct lookup tag;
- struct lookup *fld;
- struct parser *next;
-};
-
-
-/*
- * cfglist description
- *
- * ________
- * | | the header has (with other things) an array
- * | header | of h_cfg[n].l_size entries. index 4
- * disk layout | | contains cfp->cf_head->h_cfg[4].l_size.
- * |________|
- * cfgfile-mapped->| |
- * CFG_DEFAULT_PARSE_SIZE | parser | cache_hint.device.wrthru.nordcache.cnode
- * | |
- * |________|
- * cfp->cf_head->h_ccopy1>| |
- * CFG_DEFAULT_SSIZE | data | null terminated strings grouped together
- * | copy 1 | in order of cfglist offset. ie data at
- * |________| offset 0 is from h_cfgs[0].l_entry
- * cfp->cf_head->h_ccopy2>| |
- * CFG_DEFAULT_SSIZE | data |
- * | copy 2 | same as above, used for two stage commit
- * |________|
- * cfp->cf_head->h_sizes1>| | here is where lists of sizes go for each
- * CFG_DEFAULT_PSIZE | sizes | cfglist. each array is preceded by the num
- * | copy 1 | of entries. |5|120|130|140|103|125|10|25 is
- * |________| a list with 5 entries 120,130,140,103,125
- * cfp->cf_head->h_sizes2>| | these numbers are used to rebuild l_nentry
- * CFG_DEFAULT_PSIZE | sizes | and l_esiz fields in h_cfg[n]
- * | copy 2 | this list is done as a two stage commit
- * |________|
- *
- *
- *
- * Data is read into cfp->cf_head->h_ccopy1 and cfp->cf_head->h_ccopy2
- * along with thier corresponding size metadata in cfp->cf_head->h_sizes1
- * and cfp->cf_head->h_sizes2. This infomation is used to rebuild the
- * cfglist structures seen below. The data in the cfglist structure is then
- * the ONLY valid data. Additions and/or deletions to the database is done
- * by moving around the cfglists and doing the right things with the size
- * arrays, the actual entries, total list sizes, the total of all the sizes of
- * all the cfglists and memory allocation. After addition/deletions are done,
- * and cfg_close is called, all of the lists are placed back into h_cparse
- * (which is really h_ccopy1 or h_ccopy2) the persistent lists are placed
- * into h_sizes (which is really h_sizes1 or h_sizes2).
- * A copy of each cfglist[n].l_size is kept in the header
- * (cfgheader->cfgsizes[n]).
- *
- *
- *
- *
- * h_cfgs h_cfgs[3]
- * head |-[0]- /|-l_name == sndr
- * |- /|-[1]- / |-l_entry == host dev bmap host..ip sync '\0' ...
- * file |- / |-[2]- / |-l_esiz[0..l_nentry - 1] == [130, 132, 135, 133,..]
- * |--|---------|-[3]---- |-l_enabled[0..l_nentry - 1] == [1,0,0,1,1]
- * |- \ |-[4]- \ |-l_nentry == 5
- * |- \|-[5]- \ |-l_index == 3
- * |-[n]- \|-l_free == 50537
- * |-l_size == 663 (130 + 132 + 135 + 133 + 133)
- *
- *
- *
- * l_name - is set when the parser is read.
- * It is the first tag of a line of parser text.
- * l_entry - is a pointer to the beginning of the null terminated string
- * list that belongs to the cfglist tagged with l_name.
- * l_esiz - is a list of sizes of the strings contained in l_entry.
- * l_esiz[0] tells the size of the string at l_entry[0].
- * l_esiz[n] is the size of the string that begins
- * at l_entry + l_esiz[0] + l_esiz[1]..+ l_esize[n - 1]
- * l_enabled - is a list of ones and zeros telling if this entry is alive
- * in the kernel. indexing is the same as l_esiz. (not implemented)
- * l_index - is the index of the parser tree that corresponds to l_name
- * and is set when the parser tree is built
- * l_free - is how memory is managed. Memory is allocated on a
- * DEFAULT_ENTRY_SIZE boundry.
- * the size of the balance of available memory at the end of l_entry
- * is kept here. when this number is lower than the string we need to add,
- * another block of memory is allocated for l_entry and the balance of
- * the size is added to l_free.
- * l_size - is size of this list. It is the summation of l_esiz[0..n]
- *
- */
-
-typedef struct cfglist {
- char *l_name; /* name of list sndr, ii.. */
- char *l_entry; /* start of list */
- int *l_esiz; /* array of sizes of entries */
- int l_nentry; /* number of entries */
- int l_index; /* index in relation to parser position */
- uint_t l_free; /* num of characters available */
- int l_size; /* size of list */
-} cfglist_t;
-
-/* note: this does not imply DEFAULT_NENTRIES * DEFAULT_ENTRY_SIZE */
-#define DEFAULT_NENTRIES 100 /* value for l_esiz sizes array */
-#define DEFAULT_ENTRY_SIZE (50 * CFG_MAX_BUF) /* 50K for each l_entry */
-
-
-typedef struct cfgheader {
- int32_t h_magic;
- int h_state; /* State flag see below */
- time_t h_stamp; /* time stamp of last update */
- long h_lock; /* lock for update */
- long h_size; /* total file size */
- int h_parseoff; /* parser config offset */
- int h_parsesize; /* parser config size */
- char *h_cparse; /* start of configuration */
- int h_csize; /* size of config section */
- int h_acsize; /* size of alternate config section */
- int *h_sizes; /* sizes of lists */
- int h_psize; /* size of persistent section */
- int h_apsize; /* size of alternate persistent section */
- char *h_ccopy1; /* base of config section 1 */
- char *h_ccopy2; /* base of config section 2 */
- int *h_sizes1; /* sizes of lists on disk 1 */
- int *h_sizes2; /* sizes of lists on disk 2 */
- int h_seq1; /* Sequenece number copy 1 both sections */
- int h_seq2; /* Sequenece number copy 2 both sections */
- char h_ncfgs; /* number of cfgs */
- cfglist_t *h_cfgs; /* start of cfg lists */
- int h_cfgsizes[MAX_CFG]; /* Sizes of configs */
-} cfgheader_t;
-
-#define CFG_HDR_GOOD 0x1
-#define CFG_HDR_INVALID 0x2
-#define CFG_HDR_RDLOCK 0x4
-#define CFG_HDR_WRLOCK 0x8
-
-struct cfg_io_s; /* forward reference */
-typedef struct cfp {
- int cf_fd; /* file descriptor */
- int cf_flag; /* flags - see below */
- long cf_size; /* size of file in fbas */
- int cf_lock; /* lock file descriptor */
- char *cf_mapped; /* mapped location via mmap */
- char *cf_name; /* file name */
- cfgheader_t *cf_head; /* header */
- struct cfg_io_s *cf_pp; /* i/o provider */
-} cfp_t;
-
-typedef struct cfgfile {
- void *cf_node; /* node filter */
- cfp_t cf[2]; /* local & optional cluster file */
-} CFGFILE;
-
-typedef struct cfg_io_s {
- struct cfg_io_s *next; /* Link to next module */
- char *name; /* name of provider */
- cfp_t *(*open)(cfp_t *, char *); /* Open device */
- void (*close)(cfp_t *); /* Close device */
- int (*seek)(cfp_t *, int, int); /* Seek */
- int (*read)(cfp_t *, void *, int); /* read */
- int (*write)(cfp_t *, void *, int); /* write */
- char *(*readcf)(cfp_t *, char *, int, int); /* Read mem config */
- int (*addcf)(cfp_t *, char *, int); /* add to mem config */
- int (*remcf)(cfp_t *, int, int); /* remove an entry */
- int (*replacecf)(cfp_t *, char *, int, int); /* replace entry */
-} cfg_io_t;
-
-#define CFG_FILE 0x1 /* database is in a regular file */
-#define CFG_NOREWIND 0x4 /* don't rewind for each get_string */
-#define CFG_NOWRVTOC 0x8 /* sector starts in vtoc land, skip it */
-#define CFG_RDONLY 0x10 /* database is read only */
-
-/*
- * constants
- */
-#define CFG_RDEV_LOCKFILE "/var/tmp/.dscfg.lck"
-#define CFG_NEW_MAGIC 0x4d414749 /* MAGI */
-#define CFG_DEFAULT_PARSE_SIZE (16 * 1024)
-#define CFG_DEFAULT_SSIZE (2 * 1024 * 1024)
-#define CFG_DEFAULT_PSIZE (512 * 1024)
-#define CFG_DEFAULT_OLDSIZE (96 * 1024)
-#define CFG_CONFIG_SIZE (CFG_DEFAULT_PARSE_SIZE + \
- (2 * CFG_DEFAULT_SSIZE) + \
- (2 * CFG_DEFAULT_PSIZE))
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CFG_IMPL_H */
diff --git a/usr/src/lib/libdscfg/common/cfg_local.c b/usr/src/lib/libdscfg/common/cfg_local.c
deleted file mode 100644
index 1b243b1a6d..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_local.c
+++ /dev/null
@@ -1,653 +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/vtoc.h>
-#include <sys/wait.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 <sys/mman.h>
-
-#include <locale.h>
-#include <langinfo.h>
-#include <libintl.h>
-#include <stdarg.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-
-#include "cfg_impl.h"
-#include "cfg.h"
-#include "cfg_local.h"
-
-#if 0
-#define DEBUG_CFGLIST
-#define DEBUG_CFGLISTRM
-#endif
-
-extern int cfg_severity;
-extern char *cfg_perror_str;
-
-long
-get_bsize(cfp_t *cfp, char *name)
-{
- char char_name[PATH_MAX];
- char *rest;
- struct vtoc vtoc;
- int slice;
- int fd;
-
- if (strlen(name) >= PATH_MAX - 1)
- return (0);
-
- rest = strstr(name, "/dsk/");
- if (rest == NULL) {
- if ((rest = strstr(name, "/rdsk/")) == NULL)
- return (0);
- strcpy(char_name, name);
- goto do_open;
-
- }
- strcpy(char_name, name);
- char_name[strlen(name) - strlen(rest)] = 0;
- strcat(char_name, "/rdsk/");
- strcat(char_name, rest + 5);
-
-do_open:
- fd = open(char_name, O_RDONLY);
- if (fd < 0)
- return (0);
-
- slice = read_vtoc(fd, &vtoc);
- if (slice < 0) {
- (void) close(fd);
- return (0);
- }
-
- (void) close(fd);
- if (vtoc.v_part[slice].p_start < CFG_VTOC_SIZE)
- cfp->cf_flag |= CFG_NOWRVTOC;
-
- return (vtoc.v_part[slice].p_size);
-}
-
-/*
- * round up to the next block size
- */
-int
-get_block_size(int size)
-{
- int ret;
-
- if (size % CFG_BLOCK_SIZE != 0)
- ret = size + CFG_BLOCK_SIZE - (size % CFG_BLOCK_SIZE);
- else
- ret = size;
- return (ret);
-}
-
-/*
- * get a chunk of mem rounded up to next block size
- */
-char *
-get_block_buf(int size)
-{
- int blk_size;
- char *blk_buf;
-
- blk_size = get_block_size(size);
-
- if ((blk_buf = (char *)calloc(blk_size, sizeof (char))) == NULL) {
- cfg_severity = CFG_EFATAL;
- cfg_perror_str = dgettext("cfg", strerror(errno));
- return (NULL);
- }
- return (blk_buf);
-}
-
-void
-free_block_buf(char *buf)
-{
- if (buf)
- free(buf);
-}
-
-void
-localcf_close(cfp_t *cfp)
-{
- fsync(cfp->cf_fd);
- cfp_unlock(cfp);
- close(cfp->cf_fd);
-}
-
-
-/*
- * cfg_open
- * Open the current configuration file
- * Sets file descriptor in cfp->cf_fd for use by other routines
- */
-cfp_t *
-localcf_open(cfp_t *cfp, char *name)
-{
- struct stat sb;
- int rc;
-
-
- if (name == NULL) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: unable to open configuration location");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
-
- cfp->cf_fd = open(name, O_RDWR|O_CREAT|O_DSYNC|O_RSYNC, 0640);
- if (cfp->cf_fd == -1) {
- if ((cfp->cf_fd = open(name, O_RDONLY, 0640)) == -1) {
- cfg_perror_str = dgettext("cfg",
- "cfg_open: unable to open configuration location");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
- cfp->cf_flag |= CFG_RDONLY;
- }
-
- if (fstat(cfp->cf_fd, &sb) == -1) {
- close(cfp->cf_fd);
- cfg_perror_str = dgettext("cfg",
- "cfg_open: unable to stat configuration location");
- cfg_severity = CFG_EFATAL;
- return (NULL);
- }
-
-
- if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
- cfp->cf_size = get_bsize(cfp, name);
-
- /* skip the vtoc if necessary */
- if (cfp->cf_flag & CFG_NOWRVTOC) {
- do {
- rc = lseek(cfp->cf_fd, CFG_VTOC_SKIP, SEEK_SET);
- } while (rc == -1 && errno == EINTR);
-
- if (rc == -1) {
- cfg_perror_str = dgettext("cfg",
- strerror(errno));
- cfg_severity = CFG_EFATAL;
- close(cfp->cf_fd);
- return (NULL);
- }
- }
-
- } else if (S_ISREG(sb.st_mode)) {
- cfp->cf_flag |= CFG_FILE;
- cfp->cf_size = FBA_NUM(FBA_SIZE(1) - 1 + sb.st_size);
- } else {
- cfg_perror_str = dgettext("cfg", "cfg_open: unknown file type");
- cfg_severity = CFG_EFATAL;
- close(cfp->cf_fd);
- cfp->cf_fd = NULL;
- return (NULL);
- }
- return (cfp);
-}
-
-int
-localcf_seekblk(cfp_t *cfp, int off, int mode)
-{
- int rc;
-
- do {
- rc = lseek(cfp->cf_fd, off, mode);
- } while (rc == -1 && errno == EINTR);
-
- return (rc);
-}
-
-int
-localcf_readblk(cfp_t *cfp, void *buf, int size)
-{
- int rc;
-
- do {
- rc = read(cfp->cf_fd, buf, size);
- } while (rc == -1 && errno == EINTR);
-
- return (rc);
-}
-
-int
-localcf_writeblk(cfp_t *cfp, void *buf, int size)
-{
- int rc;
-
- do {
- rc = write(cfp->cf_fd, buf, size);
- } while (rc == -1 && errno == EINTR);
-
- return (rc);
-}
-
-int
-localcf_seek(cfp_t *cfp, int off, int mode)
-{
- int rc;
- int offset;
-
- offset = get_block_size(off);
-
- if ((mode == SEEK_SET) && (cfp->cf_flag & CFG_NOWRVTOC)) {
- offset += CFG_VTOC_SKIP;
- }
-
- do {
- rc = lseek(cfp->cf_fd, offset, mode);
- } while (rc == -1 && errno == EINTR);
-
- return (rc);
-}
-
-int
-localcf_read(cfp_t *cfp, void *buf, int size)
-{
- int rc;
- int blk_size;
- char *blk_buf;
-
- blk_size = get_block_size(size);
- if ((blk_buf = get_block_buf(size)) == NULL)
- return (-1);
-
- do {
- rc = read(cfp->cf_fd, blk_buf, blk_size);
- } while (rc == -1 && errno == EINTR);
-
- bcopy(blk_buf, buf, size);
- free_block_buf(blk_buf);
-
- return (rc);
-}
-
-int
-localcf_write(cfp_t *cfp, void *buf, int size)
-{
- int rc;
- int blk_size;
- char *blk_buf;
-
- blk_size = get_block_size(size);
- if ((blk_buf = get_block_buf(size)) == NULL)
- return (-1);
-
- bcopy(buf, blk_buf, size);
-
- do {
- rc = write(cfp->cf_fd, blk_buf, blk_size);
- } while (rc == -1 && errno == EINTR);
-
- free_block_buf(blk_buf);
-
- return (rc);
-}
-/*
- * Routines which operate on internal version of configuration
- */
-
-/*
- * Add entry to end of configuration section
- */
-
-int
-addcfline(cfp_t *cfp, char *line, int table_index)
-{
- int len = strlen(line)+1;
- int newsize = DEFAULT_ENTRY_SIZE / 2;
- cfgheader_t *hd;
- cfglist_t *cfl;
- char *q;
-
-#ifdef DEBUG_CFGLIST
- fprintf(stderr, "addcfline: pre l_size %d h_cfgsizes[%d]"
- " %d l_free %u adding len %d\n",
- cfp->cf_head->h_cfgs[table_index].l_size, table_index,
- cfp->cf_head->h_cfgsizes[table_index],
- cfp->cf_head->h_cfgs[table_index].l_free, len);
-#endif
-
- hd = cfp->cf_head;
- cfl = &cfp->cf_head->h_cfgs[table_index];
- if (cfl->l_free < len) {
-
-#ifdef DEBUG_CFGLIST
- fprintf(stderr, "resizing l_entry from %d to %d\n",
- cfl->l_size + cfl->l_free, cfl->l_size +
- cfl->l_free + newsize);
-#endif
- cfl->l_entry = (char *)realloc(cfl->l_entry, (cfl->l_size +
- cfl->l_free + newsize) * sizeof (char));
- if (cfl->l_entry == NULL) {
- errno = ENOMEM;
- return (-1);
- }
- cfl->l_free += newsize;
-
- }
- cfl->l_free -= len;
-
- /* out of list slots, get some more */
- if (cfl->l_nentry % DEFAULT_NENTRIES == 0) {
- /*
- * first, figure out how much bigger, than realloc
- */
-
-#ifdef DEBUG_CFGLIST
- fprintf(stderr,
- "list %d getting more nentries, I have %d\n",
- table_index, cfl->l_nentry);
-#endif
- cfl->l_esiz = (int *)
- realloc(cfl->l_esiz, (cfl->l_nentry + DEFAULT_NENTRIES) *
- sizeof (int));
- if (cfl->l_esiz == NULL) {
- errno = ENOMEM;
- return (-1);
- }
- }
-
-
- cfl->l_esiz[cfl->l_nentry] = len;
- cfl->l_nentry++;
-
- /* add line to end of list */
- q = cfl->l_entry + cfl->l_size;
-
- strcpy(q, line);
- q += len;
-
- /* set sizes */
- hd->h_cfgs[table_index].l_size += len;
- hd->h_cfgsizes[table_index] = cfl->l_size;
- cfp->cf_head->h_csize += len;
-
-#ifdef DEBUG_CFGLIST
- fprintf(stderr, "addcfline: post l_size %d h_cfgsizes[%d]"
- " %d l_free %u\n h_csize %d\n",
- cfp->cf_head->h_cfgs[table_index].l_size,
- table_index, cfp->cf_head->h_cfgsizes[table_index],
- cfp->cf_head->h_cfgs[table_index].l_free, cfp->cf_head->h_csize);
-#endif
-
- return (1);
-}
-
-/*
- * remove entry from configuration section
- */
-int
-remcfline(cfp_t *cfp, int table_offset, int setnum)
-{
- cfgheader_t *ch;
- char *p, *q;
- int len;
- int copylen;
- int i;
- cfglist_t *cfl;
- ch = cfp->cf_head;
-
- cfl = &cfp->cf_head->h_cfgs[table_offset];
-
- q = cfl->l_entry;
-
- if (cfl->l_size == 0) {
- /* list is empty */
- return (-1);
- }
-
- if (!q) { /* somethings wrong here */
- return (-1);
- }
-
-
- for (i = 1; i < setnum; i++) {
- q += cfl->l_esiz[i - 1];
- if (i >= cfl->l_nentry) { /* end of list */
- return (-1);
- }
- }
-
- if (q >= cfl->l_entry + cfl->l_size)
- return (-1);
-
- len = cfl->l_esiz[i - 1];
-
-
-#ifdef DEBUG_CFGLISTRM
- fprintf(stderr, "remcfline: pre: l_size %d h_cfgsizes[%d] %d free %d"
- " removing len %d\n",
- ch->h_cfgs[table_offset].l_size, table_offset,
- ch->h_cfgsizes[table_offset],
- ch->h_cfgs[table_offset].l_free, len);
-#endif
-
- p = q + len; /* next string */
-
- if (!(p >= cfl->l_entry + cfl->l_size)) {
- /* if we didn't delete the last string in list */
- /* LINTED possible overflow */
- copylen = cfl->l_entry + cfl->l_size - p;
- bcopy(p, q, copylen);
- copylen = (cfl->l_nentry - i) * sizeof (int);
- bcopy(&cfl->l_esiz[i], &cfl->l_esiz[i - 1], copylen);
- }
-
- /* decrement the number of sets in this list */
- cfl->l_nentry--;
- /* not really necessary, but.. */
- cfl->l_esiz[cfl->l_nentry] = 0;
-
- cfl->l_size -= len;
- cfl->l_free += len;
-
- p = cfl->l_entry + cfl->l_size;
- bzero(p, cfl->l_free);
-
- ch->h_cfgsizes[table_offset] = cfl->l_size;
- ch->h_csize -= len;
-
-
-#ifdef DEBUG_CFGLIST
- fprintf(stderr,
- "remcfline: post: l_size %d h_cfgsizes[%d] %d free %d\n ",
- ch->h_cfgs[table_offset].l_size, table_offset,
- ch->h_cfgsizes[table_offset], ch->h_cfgs[table_offset].l_free);
-#endif
-
- return (0);
-
-}
-/*
- * Read entry from configuration section
- */
-char *
-readcfline(cfp_t *cfp, char *buf, int table_offset, int num)
-{
-
- char *q;
- int i;
- cfgheader_t *ch;
- cfglist_t *cfl;
-
- /* this means they couldn't even find it in the parser tree */
- if (table_offset < 0)
- return (NULL);
-
- ch = cfp->cf_head;
- cfl = &ch->h_cfgs[table_offset];
-
- q = cfl->l_entry;
-
- for (i = 1; i < num; i++) {
- q += cfl->l_esiz[i - 1];
- if (i >= cfl->l_nentry) /* end of list */
- return (NULL);
- }
-
- if (q >= cfl->l_entry + cfl->l_size)
- return (NULL);
- strcpy(buf, q);
- return (q);
-}
-
-
-/*
- * overwrite from current position with new value
- */
-int
-replacecfline(cfp_t *cfp, char *line, int table_offset, int num)
-{
-/*
- * take a table offset and a num to replace
- * index in, bump the list up, leaving a hole big
- * enough for the new string, or bcopying the rest of the list
- * down only leaving a hole big enough.
- * make sure not to overflow the
- * allocated list size.
- */
- cfgheader_t *ch;
- cfglist_t *cfl;
- char *p, *q;
- int len = strlen(line) + 1;
- int diff = 0;
- int i;
- int newsize = DEFAULT_ENTRY_SIZE / 2;
-
-
- ch = cfp->cf_head;
- cfl = &ch->h_cfgs[table_offset];
-
- q = cfl->l_entry;
- for (i = 1; i < num; i++) {
- q += cfl->l_esiz[i - 1];
- if (i >= cfl->l_nentry) /* end of list */
- return (-1);
- }
- diff = len - cfl->l_esiz[i - 1];
- /* check for > 0, comparing uint to int */
- if ((diff > 0) && (diff > cfl->l_free)) {
- /*
- * we are going to overflow, get more mem, but only
- * 1/2 as much as initial calloc, we don't need to be greedy
- */
-#ifdef DEBUG_CFGLIST
- fprintf(stderr,
- "resizing at replacecfline from %d to %d \n",
- cfl->l_size + cfl->l_free, cfl->l_size +
- cfl->l_free + newsize);
-#endif
- cfl->l_entry = (char *)realloc(cfl->l_entry,
- (cfl->l_size + cfl->l_free + newsize) * sizeof (char));
- if (cfl->l_entry == NULL) {
- errno = ENOMEM;
- return (-1);
- }
- cfl->l_free += (DEFAULT_ENTRY_SIZE / 2);
-
- /* re-find q, we could have a whole new chunk of memory here */
- q = cfl->l_entry;
- for (i = 1; i < num; i++) {
- q += cfl->l_esiz[i - 1];
- if (i >= cfl->l_nentry) /* end of list */
- return (-1);
- }
- }
-
- p = q + cfl->l_esiz[i - 1]; /* next string */
- cfl->l_esiz[i - 1] += diff; /* the new entry size */
- if (diff != 0) { /* move stuff over/back for correct fit */
- /* LINTED possible overflow */
- bcopy(p, p + diff, (cfl->l_entry + cfl->l_size - p));
- cfl->l_free -= diff; /* 0 - (-1) = 1 */
- cfl->l_size += diff;
-
- /* total of all h_cfgs[n].l_entry */
- cfp->cf_head->h_csize += diff;
- cfp->cf_head->h_cfgsizes[table_offset] = cfl->l_size; /* disk */
- bzero((cfl->l_entry + cfl->l_size), cfl->l_free);
- }
-
- strcpy(q, line);
- return (1);
-
-}
-
-static cfg_io_t _cfg_raw_io_def = {
- NULL,
- "Local",
- localcf_open,
- localcf_close,
- localcf_seek,
- localcf_read,
- localcf_write,
- readcfline,
- addcfline,
- remcfline,
- replacecfline,
-
-};
-
-static cfg_io_t _cfg_block_io_def = {
- NULL,
- "Local",
- localcf_open,
- localcf_close,
- localcf_seekblk,
- localcf_readblk,
- localcf_writeblk,
- readcfline,
- addcfline,
- remcfline,
- replacecfline,
-};
-
-cfg_io_t *
-cfg_raw_io_provider(void)
-{
- return (&_cfg_raw_io_def);
-}
-
-cfg_io_t *
-cfg_block_io_provider(void)
-{
- return (&_cfg_block_io_def);
-}
diff --git a/usr/src/lib/libdscfg/common/cfg_local.h b/usr/src/lib/libdscfg/common/cfg_local.h
deleted file mode 100644
index 5dff884baf..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_local.h
+++ /dev/null
@@ -1,42 +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 _CFG_LOCAL_H
-#define _CFG_LOCAL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-char *readcfline(cfp_t *cfp, char *buf, int table_index, int offset);
-int addcfline(cfp_t *cfp, char *line, int table_index);
-int replacecfline(cfp_t *cfp, char *line, int table_index, int offset);
-int remcfline(cfp_t *cfp, int table_index, int offset);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CFG_LOCAL_H */
diff --git a/usr/src/lib/libdscfg/common/cfg_lockd.h b/usr/src/lib/libdscfg/common/cfg_lockd.h
deleted file mode 100644
index 42fbc6d676..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_lockd.h
+++ /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.
- */
-
-#ifndef _CFG_LOCKD_H
-#define _CFG_LOCKD_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum { LOCK_NOTLOCKED, /* Unlock message */
- LOCK_READ, /* ask for read lock */
- LOCK_WRITE, /* ask for write lock */
- LOCK_LOCKED, /* lock has been taken */
- LOCK_LOCKEDBY, /* who has lock? */
- LOCK_STAT, /* ask daemon to print its state */
- LOCK_ACK /* acknowledge a notlocked msg */
- } cfglockd_t;
-
-typedef struct sockaddr_in daemonaddr_t;
-
-struct lock_msg {
- int32_t message;
- pid_t pid;
- int32_t order;
- uint8_t seq;
-};
-
-#define CFG_PIDFILE "/var/tmp/.cfglockd.pid"
-#define CFG_SERVER_PORT 50121u
-#define CFG_LF_EOF -1
-#define CFG_LF_OKAY 1
-#define CFG_LF_AGAIN 0
-void cfg_lfinit();
-int cfg_filelock(int segment, int flag);
-int cfg_fileunlock(int segment);
-void cfg_readpid(int segment, pid_t *pidp);
-void cfg_writepid(int segment, pid_t pid);
-void cfg_enterpid();
-int cfg_lockd_init();
-cfglockd_t cfg_lockedby(pid_t *);
-void cfg_lockd_rdlock();
-void cfg_lockd_wrlock();
-void cfg_lockd_unlock();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CFG_LOCKD_H */
diff --git a/usr/src/lib/libdscfg/common/cfg_lockdlck.c b/usr/src/lib/libdscfg/common/cfg_lockdlck.c
deleted file mode 100644
index 14f7cb4b1d..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_lockdlck.c
+++ /dev/null
@@ -1,135 +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 <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <strings.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "cfg_impl.h"
-#include "cfg_lockd.h"
-
-
-#define segment_off(s) ((off_t)(s) * sizeof (pid_t))
-
-static int local_lockfd;
-static int local_lockfda;
-
-void
-cfg_lfinit()
-{
- local_lockfd = open(CFG_RDEV_LOCKFILE, O_RDWR|O_CREAT, 0644);
- local_lockfda = open(CFG_RDEV_LOCKFILE, O_RDWR|O_APPEND, 0644);
-}
-
-int
-cfg_filelock(int segment, int flag)
-{
- struct flock lk;
- struct stat sb;
- pid_t pid = 0;
- off_t off = segment_off(segment);
- int rc;
-
- while (fstat(local_lockfd, &sb) == -1 && errno == EINTR)
- ;
- if (sb.st_size < off + sizeof (pid_t)) {
- if ((flag&O_CREAT) == 0)
- return (CFG_LF_EOF);
- write(local_lockfda, &pid, sizeof (pid_t));
- }
- bzero(&lk, sizeof (lk));
- lk.l_type = F_WRLCK;
- lk.l_whence = SEEK_SET;
- lk.l_start = off;
- lk.l_len = (off_t)sizeof (pid_t);
-
- while ((rc = fcntl(local_lockfd, F_SETLK, &lk)) < 0 && errno == EINTR)
- ;
- if (rc == -1 && errno == EAGAIN)
- return (CFG_LF_AGAIN);
-
- return (CFG_LF_OKAY);
-}
-
-
-int
-cfg_fileunlock(int segment)
-{
- struct flock lk;
- off_t off = segment_off(segment);
-
- bzero(&lk, sizeof (lk));
- lk.l_type = F_UNLCK;
- lk.l_whence = SEEK_SET;
- lk.l_start = off;
- lk.l_len = (off_t)sizeof (pid_t);
-
- while (fcntl(local_lockfd, F_SETLK, &lk) < 0 && errno == EINTR)
- ;
- return (1);
-}
-
-void
-cfg_readpid(int segment, pid_t *pidp)
-{
- off_t off = segment_off(segment);
- lseek(local_lockfd, off, SEEK_SET);
- read(local_lockfd, pidp, sizeof (pid_t));
-}
-
-void
-cfg_writepid(int segment, pid_t pid)
-{
- off_t off = segment_off(segment);
- lseek(local_lockfd, off, SEEK_SET);
- write(local_lockfd, &pid, sizeof (pid_t));
-}
-
-void
-cfg_enterpid()
-{
- int i;
- pid_t pid;
-
- for (i = 0; ; i++) {
- if (cfg_filelock(i, O_CREAT) == CFG_LF_OKAY) {
- cfg_readpid(i, &pid);
- if (pid != (pid_t)0) {
- cfg_fileunlock(i);
- continue;
- }
- pid = getpid();
- cfg_writepid(i, pid);
- break;
- }
- }
-}
diff --git a/usr/src/lib/libdscfg/common/cfg_lockdmsg.c b/usr/src/lib/libdscfg/common/cfg_lockdmsg.c
deleted file mode 100644
index 238c75967e..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_lockdmsg.c
+++ /dev/null
@@ -1,324 +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 <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include "cfg_lockd.h"
-
-static daemonaddr_t clientaddr;
-static daemonaddr_t server;
-
-static unsigned short server_port = CFG_SERVER_PORT;
-static int lock_soc = 0;
-static int pf_inet = AF_INET;
-static int locked;
-static int initdone;
-static int initresult;
-static pid_t socket_pid;
-
-static void cfg_lockd_reinit();
-
-static int last_cmd = -1;
-static uint8_t seq = 0;
-
-static void
-send_cmd(int cmd)
-{
- struct lock_msg message_buf;
- int rc;
-
- if (last_cmd == cmd) {
- message_buf.seq = seq;
- } else {
- message_buf.seq = ++seq;
- last_cmd = cmd;
- }
- message_buf.message = cmd;
- if ((message_buf.pid = getpid()) != socket_pid)
- cfg_lockd_reinit();
-
- do {
- rc = sendto(lock_soc, &message_buf, sizeof (message_buf), 0,
- (struct sockaddr *)&server, sizeof (server));
- } while (rc == -1 && errno == EINTR);
-#ifdef CFG_LOCKD_DEBUG
- if (rc < 0) {
- perror("send");
- }
-#endif
-}
-
-static void
-read_msg(struct lock_msg *mp)
-{
- struct sockaddr from;
- int rc, len;
-
- /* wait for response */
- do {
- struct pollfd fds;
-
- fds.fd = lock_soc;
- fds.events = POLLIN;
- fds.revents = 0;
-
- rc = poll(&fds, 1, 500);
- if (!rc) {
-#ifdef CFG_LOCKD_DEBUG
- fprintf(stderr, "LOCKD: resending last command (%d)\n",
- last_cmd);
-#endif
- send_cmd(last_cmd);
- }
- } while (rc == 0 ||
- (rc == -1 && errno == EINTR));
-
- do {
- len = sizeof (from);
- rc = recvfrom(lock_soc, mp, sizeof (*mp), 0,
- &from, &len);
- } while (rc == -1 && errno == EINTR);
-#ifdef CFG_LOCKD_DEBUG
- if (rc < 0) {
- perror("revcfrom");
- }
-#endif
-}
-
-static void
-read_reply()
-{
- struct lock_msg message_buf;
-
- do {
- read_msg(&message_buf);
- } while (message_buf.seq != seq || message_buf.message != LOCK_LOCKED);
-}
-
-static void
-read_ack()
-{
- struct lock_msg message_buf;
-
- do {
- read_msg(&message_buf);
- } while (message_buf.seq != seq || message_buf.message != LOCK_ACK);
-}
-
-void
-cfg_lockd_rdlock()
-{
-#ifdef CFG_LOCKD_DEBUG
- FILE *fp;
-#endif
-
- send_cmd(LOCK_READ);
- locked = 1;
- read_reply();
-
-#ifdef CFG_LOCKD_DEBUG
- fp = fopen("/tmp/locktag", "a");
- if (fp) {
- time_t t = time(0);
- fprintf(fp, "%19.19s read lock acquired\n", ctime(&t));
- fclose(fp);
- }
- sleep(3);
-#endif
-}
-
-void
-cfg_lockd_wrlock()
-{
-#ifdef CFG_LOCKD_DEBUG
- FILE *fp;
-#endif
-
- send_cmd(LOCK_WRITE);
- locked = 1;
- read_reply();
-
-#ifdef CFG_LOCKD_DEBUG
- fp = fopen("/tmp/locktag", "a");
- if (fp) {
- time_t t = time(0);
- fprintf(fp, "%19.19s write lock acquired\n", ctime(&t));
- fclose(fp);
- }
- sleep(3);
-#endif
-}
-
-void
-cfg_lockd_unlock()
-{
-#ifdef CFG_LOCKD_DEBUG
- FILE *fp;
-#endif
-
- send_cmd(LOCK_NOTLOCKED);
- read_ack();
- locked = 0;
-
-#ifdef CFG_LOCKD_DEBUG
- fp = fopen("/tmp/locktag", "a");
- if (fp) {
- time_t t = time(0);
- fprintf(fp, "%19.19s ----- lock released\n", ctime(&t));
- fclose(fp);
- }
- sleep(3);
-#endif
-}
-
-void
-cfg_lockd_stat()
-{
- send_cmd(LOCK_STAT);
-}
-
-cfglockd_t
-cfg_lockedby(pid_t *pidp)
-{
- struct lock_msg message_buf;
- send_cmd(LOCK_LOCKEDBY);
- read_msg(&message_buf);
- *pidp = message_buf.pid;
- return ((cfglockd_t)message_buf.message);
-}
-
-static void
-cfg_atexit()
-{
- if (locked)
- cfg_lockd_unlock();
-}
-
-static int
-cfg_lockd_socket()
-{
- if ((lock_soc = socket(pf_inet, SOCK_DGRAM, 0)) < 0) {
-#ifdef CFG_LOCKD_DEBUG
- fprintf(stderr, "libcfg: failed to create socket\n");
- perror("socket");
-#endif
- return (-1);
- }
- clientaddr.sin_family = AF_INET;
- clientaddr.sin_addr.s_addr = INADDR_ANY;
- clientaddr.sin_port = htons(0);
- if (bind(lock_soc, (struct sockaddr *)&clientaddr,
- sizeof (clientaddr)) < 0) {
-#ifdef CFG_LOCKD_DEBUG
- perror("bind");
-#endif
- return (-1);
- }
- socket_pid = getpid();
- return (0);
-}
-
-/*
- * Re-initialise after a fork has been detected.
- *
- * Needs to create a new socket for new process to receive messages
- * from the lock daemon and enter pid into lock file so that the daemon
- * can detect new processes exit if it doesn't call unlock first.
- */
-
-static void
-cfg_lockd_reinit()
-{
- if (lock_soc)
- close(lock_soc);
- lock_soc = 0;
- if (cfg_lockd_socket()) {
- initresult = 0;
- return;
- }
- cfg_enterpid();
- initresult = 1;
-}
-
-int
-cfg_lockd_init()
-{
- struct hostent *hp;
- FILE *fp;
- int pid = 0x12345678;
-
- if (initdone) {
- /* only perform reinit if init worked first time */
- if (getpid() != socket_pid && initresult != 0)
- cfg_lockd_reinit();
- return (initresult);
- }
-
- initdone = 1;
- initresult = 0;
-
- /* check if there's a lock daemon out there */
- if ((fp = fopen(CFG_PIDFILE, "r")) == NULL)
- return (0);
- if (fscanf(fp, "%d\n", &pid) != 1) {
- fclose(fp);
- return (0);
- }
- fclose(fp);
- if (kill((pid_t)pid, 0) != 0)
- return (0);
-
- /* there is a lock daemon */
- cfg_lfinit();
- cfg_enterpid();
- if (cfg_lockd_socket())
- return (0);
-
- if ((hp = gethostbyname("localhost")) == NULL) {
-#ifdef CFG_LOCKD_DEBUG
- fprintf(stderr, "Can't find hostent for %s\n", "localhost");
-#endif
- return (0);
- }
- (void) memcpy(&(server.sin_addr.s_addr), *(hp->h_addr_list),
- sizeof (server.sin_addr));
- server.sin_port = htons(server_port);
- server.sin_family = hp->h_addrtype;
- endhostent();
- atexit(cfg_atexit);
- initresult = 1;
- return (1);
-}
diff --git a/usr/src/lib/libdscfg/common/cfg_vols.c b/usr/src/lib/libdscfg/common/cfg_vols.c
deleted file mode 100644
index 6f0f8bb447..0000000000
--- a/usr/src/lib/libdscfg/common/cfg_vols.c
+++ /dev/null
@@ -1,1286 +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 <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/mkdev.h>
-#include <strings.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <locale.h>
-#include <errno.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/unistat/spcs_s_impl.h>
-
-#include <sys/nsctl/sv.h>
-#include <sys/nsctl/nsc_hash.h>
-
-#define DEV_EXPAND 32
-
-#define DO_DISABLE 0
-#define DO_ENABLE 1
-
-/*
- * Utility functions for iiadm and rdcadm/sndradm.
- */
-
-typedef struct hash_data_s {
- union {
- char *users;
- char *mode;
- } u;
- char *path;
- char *node;
- int setno;
-} hash_data_t;
-
-typedef struct {
- dev_t rdev;
- mode_t mode;
- char *path;
-} device_t;
-
-static hash_data_t *make_svol_data(char *, char *, char *, int);
-static hash_data_t *make_dsvol_data(char *, char *, char *, int);
-static void delete_svol_data(void *);
-static void delete_dsvol_data(void *);
-static int sv_action(char *, CFGFILE *, char *, int);
-
-static int add_dev_entry(const char *);
-static int compare(const void *, const void *);
-static char *find_devid(const char *);
-static void free_dev_entries();
-static void rebuild_devhash();
-
-static hash_node_t **dsvol;
-static int dsvol_loaded = 0;
-
-static hash_node_t **svol;
-static int svol_loaded = 0;
-
-static hash_node_t **shadowvol;
-
-static hash_node_t **devhash;
-static device_t *devlist;
-static int devcount = 0;
-static int devalloc = 0;
-
-/*
- * cfg_add_user
- *
- * Description:
- * Adds the calling tool as a user of the volume.
- *
- * Inputs:
- * char *path: The pathname of the volume to be enabled.
- * char *cnode: The device group name, or NULL if -C local or not cluster
- * CFGFILE *cfg: A pointer to the current config file, or NULL if this
- * function is to open/write/commit/close the change itself.
- *
- * Return values:
- * CFG_USER_FIRST: Indicates that this is the first user of this
- * particular volume.
- * CFG_USER_OK: Indicates that the volume has already been entered into
- * the config file.
- * CFG_USER_ERR: Indicates that some failure has occurred and no changes
- * to the config file have been made.
- * CFG_USER_REPEAT: Indicates that this user has already registered for
- * the volume.
- */
-int
-cfg_add_user(CFGFILE* cfg, char *path, char *cnode, char *user)
-{
- int self_open, self_loaded, change_made;
- char *ctag, search_key[ CFG_MAX_KEY ], buf[ CFG_MAX_BUF ];
- int retval, rc;
- hash_data_t *data;
-
- self_open = (cfg == NULL);
- self_loaded = 0;
- change_made = 0;
-
- if (self_open) {
- cfg = cfg_open(NULL);
- if (cfg == NULL) {
- return (CFG_USER_ERR);
- }
-
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- /* oops */
- cfg_close(cfg);
- return (CFG_USER_ERR);
- }
- }
-
- /* Check cnode */
- ctag = cfg_get_resource(cfg);
- if (cnode) {
- if (ctag) {
- if (strcmp(cnode, ctag))
- return (CFG_USER_ERR);
- } else
- cfg_resource(cfg, cnode);
- } else
- cnode = ctag;
-
- if (!dsvol_loaded) {
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- self_loaded = 1;
- }
-
- /* find the volume */
- (void) snprintf(search_key, CFG_MAX_KEY, "%s:%s", path, cnode);
- data = nsc_lookup(dsvol, search_key);
-
- if (!data) {
- /* whoops, not found. Add as new user */
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(buf, CFG_MAX_BUF, "%s %s %s", path, cnode,
- user);
- rc = cfg_put_cstring(cfg, "dsvol", buf, strlen(buf));
- if (rc < 0) {
- if (self_loaded) {
- cfg_unload_dsvols();
- }
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- /* reload hash, if we need to */
- if (!self_loaded) {
- cfg_unload_dsvols();
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- }
- retval = CFG_USER_FIRST;
- change_made = 1;
- } else {
- /* Check to ensure we're not already listed */
- char *p = strdup(data->u.users);
- char *q = strtok(p, ",");
- while (q && (strcmp(q, user) != 0)) {
- q = strtok(0, ",");
- }
- free(p); /* not using data; only testing 'q' ptr */
-
- if (!q) {
- /* not listed as a user */
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(buf, CFG_MAX_BUF, "%s %s %s,%s",
- data->path, data->node, data->u.users, user);
- (void) snprintf(search_key, CFG_MAX_KEY, "dsvol.set%d",
- data->setno);
- if (cfg_put_cstring(cfg, search_key, buf,
- strlen(buf)) < 0) {
- if (self_loaded) {
- cfg_unload_dsvols();
- }
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
-
- /*
- * Since we deleted an entry from the config
- * file, we don't know what all the new
- * set numbers are. We need to reload
- * everything
- */
- if (!self_loaded) {
- cfg_unload_dsvols();
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- }
- change_made = 1;
- retval = CFG_USER_OK;
- } else {
- retval = CFG_USER_REPEAT;
- }
- }
-
- if (self_loaded) {
- cfg_unload_dsvols();
- }
-
- if (self_open) {
- if (change_made)
- (void) cfg_commit(cfg);
- cfg_close(cfg);
- }
-
- return (retval);
-}
-
-/*
- * cfg_rem_user
- *
- * Description:
- * Removes a user from the config file.
- *
- * Inputs:
- * char *path: The pathname of the volume to be enabled.
- * char *cnode: The device group name, or NULL if -C local or not cluster
- * char *user: The subsystem that is adding this tag (sv, ii, sndr)
- * CFGFILE *cfg: A pointer to the current config file, or NULL if this
- * function is to open/write/commit/close the change itself.
- * Return values:
- * CFG_USER_ERR: An error occurred during the processing of this
- * directive.
- * CFG_USER_OK: User successfully removed; volume in use by other(s).
- * CFG_USER_LAST: User successfuly removed; no other users registered
- * CFG_USER_GONE: The volume is no longer listed in the dsvol section,
- * indicating some sort of application-level error.
- *
- */
-int
-cfg_rem_user(CFGFILE *cfg, char *path, char *cnode, char *user)
-{
- int self_open, self_loaded, change_made;
- char *ctag, search_key[ CFG_MAX_KEY ], buf[ CFG_MAX_BUF ];
- char cfg_key[ CFG_MAX_KEY ];
- hash_data_t *data;
- int retval;
- int force_remove;
-
- self_open = (cfg == NULL);
- self_loaded = 0;
- change_made = 0;
- force_remove = (strcmp(user, "sv") == 0);
-
- if ('-' == *user) {
- ++user;
- }
-
- /* Check cnode */
- ctag = cfg_get_resource(cfg);
- if (cnode) {
- if (ctag) {
- if (strcmp(cnode, ctag))
- return (CFG_USER_ERR);
- } else
- cfg_resource(cfg, cnode);
- } else
- cnode = ctag;
-
- if (self_open) {
- cfg = cfg_open(NULL);
- if (cfg == NULL) {
- return (CFG_USER_ERR);
- }
-
- if (!cfg_lock(cfg, CFG_WRLOCK)) {
- /* oops */
- cfg_close(cfg);
- return (CFG_USER_ERR);
- }
- }
-
-
- change_made = 0;
- if (!dsvol_loaded) {
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- self_loaded = 1;
- }
-
- /* find the volume */
- (void) snprintf(search_key, CFG_MAX_KEY, "%s:%s", path, cnode);
- data = nsc_lookup(dsvol, search_key);
-
- if (!data) {
- /* yipes */
- retval = CFG_USER_GONE;
- } else if (force_remove) {
- retval = CFG_USER_LAST;
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(cfg_key, CFG_MAX_KEY, "dsvol.set%d",
- data->setno);
- if (cfg_put_cstring(cfg, cfg_key, NULL, 0) < 0) {
- if (self_loaded) {
- cfg_unload_dsvols();
- }
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- if (!self_loaded) {
- cfg_unload_dsvols();
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- }
- } else {
- char *p = strdup(data->u.users);
- char *q = strtok(p, ",");
- int appended = 0;
-
- (void) snprintf(buf, CFG_MAX_BUF, "%s %s ", data->path,
- data->node);
- while (q && (strcmp(q, user) != 0)) {
- if (appended) {
- strcat(buf, ",");
- strcat(buf, q);
- } else {
- strcat(buf, q);
- appended = 1;
- }
- q = strtok(0, ",");
- }
-
- if (!q) {
- /* uh-oh */
- retval = CFG_USER_GONE;
- } else {
- /* old user skipped; add in remaining users */
- while (q = strtok(0, ", ")) {
- if (appended) {
- strcat(buf, ",");
- strcat(buf, q);
- } else {
- strcat(buf, q);
- appended = 1;
- }
- }
-
- if (appended) {
- retval = CFG_USER_OK;
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(cfg_key, CFG_MAX_KEY,
- "dsvol.set%d", data->setno);
- if (cfg_put_cstring(cfg, cfg_key, buf,
- strlen(buf)) < 0) {
- if (self_loaded) {
- cfg_unload_dsvols();
- }
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- if (!self_loaded) {
- cfg_unload_dsvols();
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- }
- } else {
- retval = CFG_USER_LAST;
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(cfg_key, CFG_MAX_KEY,
- "dsvol.set%d", data->setno);
- if (cfg_put_cstring(cfg, cfg_key, NULL,
- 0) < 0) {
- if (self_loaded) {
- cfg_unload_dsvols();
- }
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- /*
- * Since we deleted an entry from the config
- * file, we don't know what all the new
- * set numbers are. We need to reload
- * everything
- */
- if (!self_loaded) {
- cfg_unload_dsvols();
- if (cfg_load_dsvols(cfg) < 0) {
- if (self_open) {
- cfg_close(cfg);
- }
- return (CFG_USER_ERR);
- }
- }
- }
- change_made = 1;
- }
- }
-
- if (self_loaded) {
- cfg_unload_dsvols();
- }
-
- if (self_open) {
- if (change_made)
- (void) cfg_commit(cfg);
- cfg_close(cfg);
- }
-
- return (retval);
-}
-
-/*
- * Enable a volume under SV control (or add this char *user to the list
- * of users of that volume).
- *
- * Parameters:
- * cfg - The config file to use.
- * path - The pathname of the volume
- * ctag - The cluster tag for this volume (if any)
- * user - The user (sv, ii, sndr) of the volume.
- */
-int
-cfg_vol_enable(CFGFILE *cfg, char *path, char *ctag, char *user)
-{
- int rc;
- int retval;
-
- if (!ctag || *ctag == '\0') {
- ctag = "-";
- }
-
- retval = -1;
- rc = cfg_add_user(cfg, path, ctag, user);
- switch (rc) {
- case CFG_USER_ERR:
- spcs_log("dsvol", NULL,
- gettext("unable to set up dsvol section of config for %s"),
- path);
- break;
- case CFG_USER_OK:
- retval = 0;
- break;
- case CFG_USER_FIRST:
- /* enable sv! */
- retval = sv_action(path, cfg, ctag, DO_ENABLE);
- if (retval < 0) {
- (void) cfg_rem_user(cfg, path, ctag, user);
- }
- break;
- default:
- spcs_log("dsvol", NULL,
- gettext("unexpected return from cfg_add_user(%d)"), rc);
- break;
- }
-
- return (retval);
-}
-
-/*
- * Disable a volume from SV control (or remove this char *user from the list
- * of users of that volume).
- *
- * Parameters:
- * cfg - The config file to use.
- * path - The pathname of the volume
- * ctag - The cluster tag for this volume (if any)
- * user - The user (sv, ii, sndr) of the volume.
- */
-int
-cfg_vol_disable(CFGFILE *cfg, char *path, char *ctag, char *user)
-{
- int rc;
- int retval;
-
- if (!ctag || *ctag == '\0') {
- ctag = "-";
- }
-
- retval = -1;
- rc = cfg_rem_user(cfg, path, ctag, user);
- switch (rc) {
- case CFG_USER_ERR:
- spcs_log("dsvol", NULL,
- gettext("unable to set up dsvol section of config for %s"),
- path);
- break;
- case CFG_USER_OK:
- retval = 0;
- break;
- case CFG_USER_GONE:
- spcs_log("dsvol", NULL,
- gettext("%s tried to remove non-existent tag for %s"),
- user, path);
- break;
- case CFG_USER_LAST:
- /* diable sv! */
- retval = sv_action(path, cfg, ctag, DO_DISABLE);
- break;
- default:
- spcs_log("dsvol", NULL,
- gettext("unexpected return from cfg_rem_user(%d)"), rc);
- break;
- }
-
- return (retval);
-}
-
-/*
- * cfg_load_dsvols
- *
- * Description:
- * Loads the dsvol section of the config file into a giant hash, to
- * make searching faster. The important bit to remember is to not
- * release the write lock between calling cfg_load_dsvols() and the
- * cfg_*_user() functions.
- *
- * Assumptions:
- * 1/ cfg file is open
- * 2/ cfg file has been write-locked
- * 3/ user of this routine may already be using hcreate/hsearch
- *
- * Return value:
- * -1 if error, or total number of sets found
- */
-int
-cfg_load_dsvols(CFGFILE *cfg)
-{
- int set, rc, entries;
- char search_key[ CFG_MAX_KEY ];
- char *buf;
- char **entry, *path, *cnode, *users;
- hash_data_t *data;
- int devs_added = 0;
- int offset = 0;
- char *ctag = cfg_get_resource(cfg);
- if (!ctag || *ctag == '\0') {
- ctag = "-";
- }
-
- dsvol = nsc_create_hash();
- if (!dsvol) {
- return (-1);
- }
-
- rc = 0;
- cfg_rewind(cfg, CFG_SEC_CONF);
- entries = cfg_get_section(cfg, &entry, "dsvol");
- for (set = 1; set <= entries; set++) {
- buf = entry[set - 1];
-
- /* split up the line */
- if (!(path = strtok(buf, " "))) {
- /* oops, now what? */
- free(buf);
- break;
- }
- if (!(cnode = strtok(0, " "))) {
- free(buf);
- break;
- }
- if (ctag && (strcmp(cnode, ctag) != 0)) {
- ++offset;
- free(buf);
- continue;
- }
-
- if (!(users = strtok(0, " "))) {
- free(buf);
- break;
- }
-
- data = make_dsvol_data(path, cnode, users, set - offset);
- if (!data) {
- free(buf);
- break;
- }
- (void) snprintf(search_key, CFG_MAX_KEY, "%s:%s", path, cnode);
- rc = nsc_insert_node(dsvol, data, search_key);
- if (rc < 0) {
- free(buf);
- break;
- }
-
- /* we also need to keep track of node information */
- rc = add_dev_entry(path);
- if (rc < 0) {
- free(buf);
- break;
- } else if (rc)
- ++devs_added;
-
- free(buf);
- rc = 0;
- }
-
- while (set < entries)
- free(entry[set++]);
- if (entries)
- free(entry);
-
- if (devs_added) {
- qsort(devlist, devcount, sizeof (device_t), compare);
- rebuild_devhash();
- }
-
- dsvol_loaded = 1;
- return (rc < 0? rc : entries);
-}
-
-/*
- * cfg_unload_dsvols
- *
- * Description:
- * Free all memory allocated with cfg_load_dsvols.
- */
-void
-cfg_unload_dsvols()
-{
- if (dsvol) {
- nsc_remove_all(dsvol, delete_dsvol_data);
- dsvol = 0;
- dsvol_loaded = 0;
- }
-}
-
-/*
- * cfg_load_svols
- *
- * Description:
- * Loads the sv section of the config file into a giant hash, to make
- * searching faster. The important bit to remember is to not release
- * the write lock between calling cfg_load_svols() and the cfg_*_user()
- * functions.
- *
- * Assumptions:
- * 1/ cfg file is open
- * 2/ cfg file has been write-locked
- * 3/ user of this routine may already be using builtin hcreate/hsearch
- */
-int
-cfg_load_svols(CFGFILE *cfg)
-{
- int set, entries, offset = 0;
- char *buf, **entry;
- char *path, *mode, *cnode;
- hash_data_t *data;
- char *ctag = cfg_get_resource(cfg);
- if (!ctag || *ctag == '\0') {
- ctag = "-";
- }
-
- svol = nsc_create_hash();
- if (!svol) {
- return (-1);
- }
-
- cfg_rewind(cfg, CFG_SEC_CONF);
- entries = cfg_get_section(cfg, &entry, "sv");
- for (set = 1; set <= entries; set++) {
- buf = entry[set - 1];
-
- /* split up the line */
- if (!(path = strtok(buf, " "))) {
- free(buf);
- break;
- }
- if (!(mode = strtok(0, " "))) {
- free(buf);
- break;
- }
- if (!(cnode = strtok(0, " "))) {
- cnode = "";
- }
-
- if (ctag && (strcmp(cnode, ctag) != 0)) {
- ++offset;
- free(buf);
- continue;
- }
-
- data = make_svol_data(path, mode, cnode, set - offset);
- if (!data) {
- free(buf);
- break;
- }
- if (nsc_insert_node(svol, data, path) < 0) {
- free(buf);
- break;
- }
- free(buf);
- }
- while (set < entries)
- free(entry[set++]);
- if (entries)
- free(entry);
-
- svol_loaded = 1;
- return (0);
-}
-
-/*
- * cfg_unload_svols
- *
- * Description:
- * Frees all memory allocated with cfg_load_dsvols
- */
-void
-cfg_unload_svols()
-{
- if (svol) {
- nsc_remove_all(svol, delete_svol_data);
- svol = 0;
- svol_loaded = 0;
- }
-}
-
-/*
- * cfg_get_canonical_name
- *
- * Description:
- * Find out whether a device is already known by another name in
- * the config file.
- *
- * Parameters:
- * cfg - The config file to use
- * path - The pathname of the device
- * result - (output) The name it is otherwise known as. This parameter
- * must be freed by the caller.
- *
- * Return values:
- * -1: error
- * 0: name is as expected, or is not known
- * 1: Name is known by different name (stored in 'result')
- */
-int
-cfg_get_canonical_name(CFGFILE *cfg, const char *path, char **result)
-{
- int self_loaded;
- char *alt_path;
- int retval;
-
- if (devlist) {
- self_loaded = 0;
- } else {
- if (cfg_load_shadows(cfg) < 0) {
- return (-1);
- }
- self_loaded = 1;
- }
-
- /* see if it exists under a different name */
- alt_path = find_devid(path);
- if (!alt_path || strcmp(path, alt_path) == 0) {
- *result = NULL;
- retval = 0;
- } else {
- /* a-ha */
- *result = strdup(alt_path);
- retval = 1;
- }
-
- if (self_loaded) {
- free_dev_entries();
- }
-
- return (retval);
-}
-
-/*
- * cfg_load_shadows
- *
- * Description:
- * Load in shadow and bitmap volumes from the II section of the
- * config file. SNDR's volumes are handled already by cfg_load_dsvols.
- * Not all shadow volumes are listed under dsvol: they can be exported.
- *
- * Parameters:
- * cfg - The config file to use
- *
- * Return values:
- * -1: error
- * 0: success
- */
-int
-cfg_load_shadows(CFGFILE *cfg)
-{
- int set, self_loaded, rc, entries;
- char *buf, **entry, *ptr;
- int devs_added = 0;
-
- if (dsvol_loaded) {
- self_loaded = 0;
- } else {
- if (cfg_load_dsvols(cfg) < 0) {
- return (-1);
- }
- self_loaded = 1;
- }
-
- shadowvol = nsc_create_hash();
- if (!shadowvol) {
- return (-1);
- }
-
- rc = 0;
- cfg_rewind(cfg, CFG_SEC_CONF);
- entries = cfg_get_section(cfg, &entry, "ii");
- for (set = 1; set <= entries; set++) {
- buf = entry[set - 1];
-
- /* skip the master vol */
- ptr = strtok(buf, " ");
-
- /* shadow is next */
- ptr = strtok(NULL, " ");
-
- rc = add_dev_entry(ptr);
- if (rc < 0) {
- free(buf);
- break;
- } else if (rc)
- ++devs_added;
-
- /* and next is bitmap */
- ptr = strtok(NULL, " ");
-
- rc = add_dev_entry(ptr);
- if (rc < 0) {
- free(buf);
- break;
- } else if (rc)
- ++devs_added;
- rc = 0;
- free(buf);
- }
- while (set < entries)
- free(entry[set++]);
- if (entries)
- free(entry);
-
- if (self_loaded) {
- cfg_unload_dsvols();
- }
-
- if (devs_added) {
- /* sort it, in preparation for lookups */
- qsort(devlist, devcount, sizeof (device_t), compare);
- rebuild_devhash();
- }
-
- return (rc);
-}
-
-void
-cfg_unload_shadows()
-{
- /* do nothing */
-}
-
-/* ---------------------------------------------------------------------- */
-
-static hash_data_t *
-make_dsvol_data(char *path, char *cnode, char *users, int set)
-{
- hash_data_t *data;
-
- data = (hash_data_t *)malloc(sizeof (hash_data_t));
- if (!data) {
- return (0);
- }
-
- data->u.users = strdup(users);
- data->path = strdup(path);
- data->node = strdup(cnode);
- data->setno = set;
-
- return (data);
-}
-
-static void
-delete_dsvol_data(void *data)
-{
- hash_data_t *p = (hash_data_t *)data;
-
- free(p->u.users);
- free(p->path);
- free(p->node);
- free(p);
-}
-
-static hash_data_t *
-make_svol_data(char *path, char *mode, char *cnode, int set)
-{
- hash_data_t *data;
-
- data = (hash_data_t *)malloc(sizeof (hash_data_t));
- if (!data) {
- return (0);
- }
-
- data->u.mode = strdup(mode);
- data->path = strdup(path);
- data->node = strdup(cnode);
- data->setno = set;
-
- return (data);
-}
-
-
-static void
-delete_svol_data(void *data)
-{
- hash_data_t *p = (hash_data_t *)data;
-
- free(p->u.mode);
- free(p->path);
- free(p->node);
- free(p);
-}
-
-static int
-sv_action(char *path, CFGFILE *caller_cfg, char *ctag, int enable)
-{
- struct stat stb;
- sv_conf_t svc;
- int fd = -1;
- int cfg_changed = 0;
- CFGFILE *cfg;
- int print_log = 0;
- int err = 0, rc;
- int sv_ioctl, spcs_err, self_loaded;
- char *log_str1, *log_str2;
- char key[ CFG_MAX_KEY ];
- char buf[ CFG_MAX_BUF ];
- hash_data_t *node;
- device_t *statinfo = 0;
-
- if (caller_cfg == NULL) {
- cfg = cfg_open(NULL);
- if (cfg == NULL)
- return (-1);
-
- if (ctag)
- cfg_resource(cfg, ctag);
- } else
- cfg = caller_cfg;
-
-
- self_loaded = 0;
- sv_ioctl = (enable? SVIOC_ENABLE : SVIOC_DISABLE);
- log_str1 = (enable? gettext("enabled %s") : gettext("disabled %s"));
- log_str2 = (enable? gettext("unable to enable %s") :
- gettext("unable to disable %s"));
- spcs_err = (enable? SV_EENABLED : SV_EDISABLED);
- bzero(&svc, sizeof (svc));
-
- if (devhash)
- statinfo = nsc_lookup(devhash, path);
-
- if (statinfo) {
- if (!S_ISCHR(statinfo->mode))
- goto error;
- svc.svc_major = major(statinfo->rdev);
- svc.svc_minor = minor(statinfo->rdev);
- } else {
- if (stat(path, &stb) != 0)
- goto error;
-
- if (!S_ISCHR(stb.st_mode))
- goto error;
- svc.svc_major = major(stb.st_rdev);
- svc.svc_minor = minor(stb.st_rdev);
- }
-
- strncpy(svc.svc_path, path, sizeof (svc.svc_path));
-
- fd = open(SV_DEVICE, O_RDONLY);
- if (fd < 0)
- goto error;
-
- svc.svc_flag = (NSC_DEVICE | NSC_CACHE);
- svc.svc_error = spcs_s_ucreate();
-
- do {
- rc = ioctl(fd, sv_ioctl, &svc);
- } while (rc < 0 && errno == EINTR);
-
- if (rc < 0) {
- if (errno != spcs_err) {
- spcs_log("sv", &svc.svc_error, log_str2, svc.svc_path);
- if (enable)
- goto error;
- else
- err = errno;
- } else
- err = spcs_err;
- }
-
- spcs_log("sv", NULL, log_str1, svc.svc_path);
-
- /* SV enable succeeded */
- if (caller_cfg == NULL) /* was not previously locked */
- if (!cfg_lock(cfg, CFG_WRLOCK))
- goto error;
-
- if (err != spcs_err) { /* already enabled, already in config */
- if (enable) {
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(buf, CFG_MAX_BUF, "%s - %s", path,
- ctag? ctag : "-");
- if (cfg_put_cstring(cfg, "sv", buf, CFG_MAX_BUF) < 0) {
- /* SV config not updated, so SV disable again */
- (void) ioctl(fd, SVIOC_DISABLE, &svc);
- print_log++;
- } else
- cfg_changed = 1;
- } else {
- /* pull it out of the config */
- if (!svol_loaded) {
- if (cfg_load_svols(cfg) < 0) {
- if (NULL == caller_cfg) {
- cfg_close(cfg);
- }
- return (-1);
- }
- self_loaded = 1;
- }
- node = nsc_lookup(svol, svc.svc_path);
- if (node) {
- cfg_rewind(cfg, CFG_SEC_CONF);
- (void) snprintf(key, CFG_MAX_KEY, "sv.set%d",
- node->setno);
- if (cfg_put_cstring(cfg, key, NULL, NULL) < 0) {
- spcs_log("sv", NULL,
- gettext("failed to remove %s from "
- "sv config"), svc.svc_path);
- }
- /*
- * Since we deleted an entry from the config
- * file, we don't know what all the new
- * set numbers are. We need to reload
- * everything
- */
- if (!self_loaded) {
- cfg_unload_svols();
- if (cfg_load_svols(cfg) < 0) {
- if (NULL == caller_cfg) {
- cfg_close(cfg);
- }
- return (-1);
- }
- }
- cfg_changed = 1;
- }
- if (self_loaded) {
- cfg_unload_svols();
- self_loaded = 0;
- }
- }
- }
-
-#ifdef lint
- (void) printf("extra line to shut lint up %s\n", module_names[0]);
-#endif
-
-error:
- if (fd >= 0)
- (void) close(fd);
-
- if (cfg == NULL)
- return (-1);
-
- if (cfg_changed)
- if (caller_cfg == NULL) /* we opened config */
- (void) cfg_commit(cfg);
-
- if (caller_cfg == NULL)
- cfg_close(cfg);
- if ((cfg_changed) || (err == spcs_err))
- return (1);
- if (print_log)
- spcs_log("sv", NULL,
- gettext("unable to add to configuration, disabled %s"),
- svc.svc_path);
- spcs_s_ufree(&svc.svc_error);
-
- return (-1);
-}
-
-/*
- * add_dev_entry
- *
- * Add an entry into the devlist and the devhash for future lookups.
- *
- * Return values:
- * -1 An error occurred.
- * 0 Entry added
- * 1 Entry already exists.
- */
-static int
-add_dev_entry(const char *path)
-{
- struct stat buf;
- device_t *newmem;
- hash_data_t *data;
-
- if (!devhash) {
- devhash = nsc_create_hash();
- if (!devhash) {
- return (-1);
- }
- } else {
- data = nsc_lookup(devhash, path);
- if (data) {
- return (1);
- }
- }
-
- if (stat(path, &buf) < 0) {
- /* ignore error, we are most likely deleting entry anyway */
- buf.st_rdev = 0;
- }
-
- if (devcount >= devalloc) {
- /* make some room */
- devalloc += DEV_EXPAND;
- newmem = (device_t *)realloc(devlist, devalloc *
- sizeof (device_t));
- if (!newmem) {
- free_dev_entries();
- return (-1);
- } else {
- devlist = newmem;
- }
- }
-
- devlist[ devcount ].path = strdup(path);
- devlist[ devcount ].rdev = buf.st_rdev;
- devlist[ devcount ].mode = buf.st_mode;
-
- if (nsc_insert_node(devhash, &devlist[devcount], path) < 0) {
- return (-1);
- }
-
- ++devcount;
- return (0);
-}
-
-static void
-rebuild_devhash()
-{
- int i;
-
- if (!devhash)
- nsc_remove_all(devhash, 0);
-
- devhash = nsc_create_hash();
- if (!devhash)
- return;
-
- for (i = 0; i < devcount; i++) {
- nsc_insert_node(devhash, &devlist[i], devlist[i].path);
- }
-}
-
-static int
-compare(const void *va, const void *vb)
-{
- device_t *a = (device_t *)va;
- device_t *b = (device_t *)vb;
-
- return (b->rdev - a->rdev);
-}
-
-static char *
-find_devid(const char *path)
-{
- device_t key;
- device_t *result;
- struct stat buf;
-
- if (!devlist || !devhash)
- return (NULL);
-
- /* See if we already know the device id by this name */
- result = (device_t *)nsc_lookup(devhash, path);
- if (result) {
- return (NULL);
- }
-
- /* try to find it by another name */
- if (stat(path, &buf) < 0)
- return (NULL);
-
- key.rdev = buf.st_rdev;
-
- /* it's storted, so we use the binary-chop method to find it */
- result = bsearch(&key, devlist, devcount, sizeof (device_t), compare);
-
- if (result) {
- return (result->path);
- }
-
- return (NULL);
-}
-
-static void
-free_dev_entries()
-{
- int i;
- device_t *p;
-
- if (!devlist) {
- return;
- }
- for (i = 0, p = devlist; i < devcount; i++, p++) {
- free(p->path);
- }
- free(devlist);
- devlist = NULL;
- devcount = 0;
- devalloc = 0;
-
- if (devhash) {
- nsc_remove_all(devhash, 0);
- devhash = NULL;
- }
-}
diff --git a/usr/src/lib/libdscfg/common/mapfile-vers b/usr/src/lib/libdscfg/common/mapfile-vers
deleted file mode 100644
index 0e1f4f4cae..0000000000
--- a/usr/src/lib/libdscfg/common/mapfile-vers
+++ /dev/null
@@ -1,100 +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.
-#
-#
-
-#
-# MAPFILE HEADER START
-#
-# WARNING: STOP NOW. DO NOT MODIFY THIS FILE.
-# Object versioning must comply with the rules detailed in
-#
-# usr/src/lib/README.mapfiles
-#
-# You should not be making modifications here until you've read the most current
-# copy of that file. If you need help, contact a gatekeeper for guidance.
-#
-# MAPFILE HEADER END
-#
-
-#
-# Generic interface definition for usr/src/lib/libcfg.
-#
-
-
-$mapfile_version 2
-
-SYMBOL_VERSION SUNWprivate_1.1 {
- global:
- cfg_get_cstring;
- cfg_put_cstring;
- cfg_find_cstring;
- cfg_get_options;
- cfg_put_options;
- cfg_open;
- cfg_close;
- cfg_rewind;
- cfg_update_parser_config;
- cfg_lock;
- cfg_unlock;
- cfg_get_lock;
- cfg_resource;
- cfg_commit;
- cfg_location;
- cfg_error;
- cfg_iscluster;
- cfg_issuncluster;
- cfg_dgname;
- cfg_dgname_islocal;
- cfg_lfinit;
- cfg_filelock;
- cfg_fileunlock;
- cfg_readpid;
- cfg_writepid;
- cfg_lockd_stat;
- cfg_invalidate_hsizes;
- cfg_cfg_isempty;
- cfg_get_section;
- cfg_get_num_entries;
- cfg_add_user;
- cfg_rem_user;
- cfg_vol_enable;
- cfg_vol_disable;
- cfg_load_dsvols;
- cfg_unload_dsvols;
- cfg_load_svols;
- cfg_unload_svols;
- cfg_load_shadows;
- cfg_unload_shadows;
- cfg_get_canonical_name;
- cfg_get_tags;
- cfg_is_cfg;
- cfg_get_srtdsec;
- cfg_free_section;
- cfg_shldskip_vtoc;
- cfg_get_single_option;
- cfg_del_option;
- cfg_get_resource;
- cfg_l_dgname;
- local:
- *;
-};