changeset 10849:426b2b7cf7e5

6857779 libiscsit should accept configuration changes even if service is offline
author Sue Gleeson <Susan.Gleeson@Sun.COM>
date Fri, 23 Oct 2009 12:38:57 -0400
parents 2cc61d58b78a
children bb29ac73664d
files usr/src/lib/libiscsit/Makefile.com usr/src/lib/libiscsit/common/libiscsit.c
diffstat 2 files changed, 62 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/libiscsit/Makefile.com	Fri Oct 23 11:50:59 2009 -0400
+++ b/usr/src/lib/libiscsit/Makefile.com	Fri Oct 23 12:38:57 2009 -0400
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -41,7 +41,7 @@
 
 C99MODE=	-xc99=%all
 C99LMODE=	-Xc99=%all
-LDLIBS +=	-lc -lnvpair -lstmf -luuid -lnsl
+LDLIBS +=	-lc -lnvpair -lstmf -luuid -lnsl -lscf
 CPPFLAGS +=	$(INCS) -D_REENTRANT
 
 SRCS=	$(OBJS_COMMON:%.o=$(SRCDIR)/%.c)			\
--- a/usr/src/lib/libiscsit/common/libiscsit.c	Fri Oct 23 11:50:59 2009 -0400
+++ b/usr/src/lib/libiscsit/common/libiscsit.c	Fri Oct 23 12:38:57 2009 -0400
@@ -32,6 +32,7 @@
 #include <unistd.h>
 #include <strings.h>
 #include <libintl.h>
+#include <libscf.h>
 
 #include <libstmf.h>
 #include <libiscsit.h>
@@ -50,6 +51,8 @@
 /* Default RADIUS server port */
 #define	DEFAULT_RADIUS_PORT	1812
 
+/* The iscsit SMF service FMRI */
+#define	ISCSIT_FMRI		"svc:/network/iscsi/target:default"
 /*
  * The kernel reserves target portal group tag value 1 as the default.
  */
@@ -80,6 +83,9 @@
 static int
 it_validate_iniprops(nvlist_t *nvl, nvlist_t *errs);
 
+static boolean_t
+is_iscsit_enabled(void);
+
 /*
  * Function:  it_config_load()
  *
@@ -168,18 +174,21 @@
 		return (EINVAL);
 	}
 
-	iscsit_fd = open(ISCSIT_NODE, O_RDWR|O_EXCL);
-	if (iscsit_fd == -1) {
-		ret = errno;
-		return (ret);
-	}
-
 	ret = it_config_to_nv(cfg, &cfgnv);
 	if (ret == 0) {
 		ret = nvlist_size(cfgnv, &pnv_size, NV_ENCODE_NATIVE);
 	}
 
-	if (ret == 0) {
+	/*
+	 * If the iscsit service is enabled, send the changes to the
+	 * kernel first.  Kernel will be the final sanity check before
+	 * the config is saved persistently.
+	 *
+	 * This somewhat leaves open the simultaneous-change hole
+	 * that STMF was trying to solve, but is a better sanity
+	 * check and allows for graceful handling of target renames.
+	 */
+	if ((ret == 0) && is_iscsit_enabled()) {
 		packednv = malloc(pnv_size);
 		if (!packednv) {
 			ret = ENOMEM;
@@ -187,24 +196,26 @@
 			ret = nvlist_pack(cfgnv, &packednv, &pnv_size,
 			    NV_ENCODE_NATIVE, 0);
 		}
-	}
 
-	/*
-	 * Send the changes to the kernel first, for now.  Kernel
-	 * will be the final sanity check before config is saved
-	 * persistently.
-	 *
-	 * XXX - this leaves open the simultaneous-change hole
-	 * that STMF was trying to solve, but is a better sanity
-	 * check.   Final decision on save order/config generation
-	 * number TBD.
-	 */
-	if (ret == 0) {
-		iop.set_cfg_vers = ISCSIT_API_VERS0;
-		iop.set_cfg_pnvlist = packednv;
-		iop.set_cfg_pnvlist_len = pnv_size;
-		if ((ioctl(iscsit_fd, ISCSIT_IOC_SET_CONFIG, &iop)) != 0) {
-			ret = errno;
+		if (ret == 0) {
+			iscsit_fd = open(ISCSIT_NODE, O_RDWR|O_EXCL);
+			if (iscsit_fd != -1) {
+				iop.set_cfg_vers = ISCSIT_API_VERS0;
+				iop.set_cfg_pnvlist = packednv;
+				iop.set_cfg_pnvlist_len = pnv_size;
+				if ((ioctl(iscsit_fd, ISCSIT_IOC_SET_CONFIG,
+				    &iop)) != 0) {
+					ret = errno;
+				}
+
+				(void) close(iscsit_fd);
+			} else {
+				ret = errno;
+			}
+		}
+
+		if (packednv != NULL) {
+			free(packednv);
 		}
 	}
 
@@ -214,6 +225,8 @@
 	 * the active service.
 	 */
 	if (ret == 0) {
+		boolean_t	changed = B_FALSE;
+
 		tgtp = cfg->config_tgt_list;
 		for (; tgtp != NULL; tgtp = tgtp->tgt_next) {
 			if (!tgtp->tgt_properties) {
@@ -223,8 +236,16 @@
 			    PROP_OLD_TARGET_NAME)) {
 				(void) nvlist_remove_all(tgtp->tgt_properties,
 				    PROP_OLD_TARGET_NAME);
+				changed = B_TRUE;
 			}
 		}
+
+		if (changed) {
+			/* rebuild the config nvlist */
+			nvlist_free(cfgnv);
+			cfgnv = NULL;
+			ret = it_config_to_nv(cfg, &cfgnv);
+		}
 	}
 
 	/*
@@ -258,12 +279,6 @@
 		}
 	}
 
-	(void) close(iscsit_fd);
-
-	if (packednv) {
-		free(packednv);
-	}
-
 	if (cfgnv) {
 		nvlist_free(cfgnv);
 	}
@@ -1917,3 +1932,18 @@
 
 	return (B_TRUE);
 }
+
+static boolean_t
+is_iscsit_enabled(void)
+{
+	char		*state;
+
+	state = smf_get_state(ISCSIT_FMRI);
+	if (state != NULL) {
+		if (strcmp(state, SCF_STATE_STRING_ONLINE) == 0) {
+			return (B_TRUE);
+		}
+	}
+
+	return (B_FALSE);
+}