changeset 3282:52f49cb5ee88

6495328 daemon should use msync on mmap'd files 6496416 iscsitadm modify admin -d <basedir> will report error if there are targets created by zvol directly 6496424 targets can not be seen if created by zvol with shareiscsi property 6499244 libiscsitgt leaks like a sieve 6505266 SUNWiscsitgtu doesn't correctly disable target during package removal
author mcneal
date Tue, 19 Dec 2006 15:46:00 -0800
parents 942a7bc8208d
children 693dbd0650cd
files usr/src/cmd/iscsi/iscsitgtd/main.c usr/src/cmd/iscsi/iscsitgtd/mgmt_modify.c usr/src/cmd/iscsi/iscsitgtd/t10_sbc.c usr/src/cmd/iscsi/iscsitgtd/t10_ssc.c usr/src/cmd/iscsi/iscsitgtd/target.h usr/src/lib/libiscsitgt/common/if_zfs.c usr/src/lib/libiscsitgt/common/xml.c usr/src/pkgdefs/SUNWiscsitgtu/preremove
diffstat 8 files changed, 145 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/iscsi/iscsitgtd/main.c	Tue Dec 19 14:40:22 2006 -0800
+++ b/usr/src/cmd/iscsi/iscsitgtd/main.c	Tue Dec 19 15:46:00 2006 -0800
@@ -250,7 +250,6 @@
 			return (False);
 		}
 
-		targets_config = node;
 		while ((next = tgt_node_next(node, XML_ELEMENT_TARG,
 		    next)) != NULL) {
 			if (tgt_find_value_str(next, XML_ELEMENT_INAME,
@@ -272,6 +271,21 @@
 		xmlTextReaderClose(r);
 		xmlFreeTextReader(r);
 		xmlCleanupParser();
+
+		/*
+		 * It's possible that nodes exist, these would be ZFS nodes.
+		 * We to move them to the new configuration tree.
+		 */
+		if (targets_config) {
+			next = NULL;
+			while ((next = tgt_node_next(targets_config,
+			    XML_ELEMENT_TARG, next)) != NULL) {
+				tgt_node_add(node, tgt_node_dup(next));
+			}
+
+			tgt_node_free(targets_config);
+		}
+		targets_config = node;
 		return (True);
 	} else {
 
@@ -821,6 +835,18 @@
 	q = queue_alloc();
 
 	/*
+	 * During the normal corse of events 'target_basedir' will be
+	 * free when the administrator changes the base directory. Instead
+	 * of trying to check for the initial case of this value being set
+	 * to some static string, always allocate that string.
+	 * NOTE: This must be done *after* process_config() is called since
+	 * it's possible and very likely that this value will be set at that
+	 * time.
+	 */
+	if (target_basedir == NULL)
+		target_basedir = strdup(DEFAULT_TARGET_BASEDIR);
+
+	/*
 	 * Initialize the various subsystems. In most cases these are
 	 * just initializing mutexs.
 	 */
--- a/usr/src/cmd/iscsi/iscsitgtd/mgmt_modify.c	Tue Dec 19 14:40:22 2006 -0800
+++ b/usr/src/cmd/iscsi/iscsitgtd/mgmt_modify.c	Tue Dec 19 15:46:00 2006 -0800
@@ -677,7 +677,8 @@
 {
 	tgt_node_t	*targ	= NULL;
 	int		count	= 0;
-	char		*msg	= NULL;
+	char		*msg	= NULL,
+			*val	= NULL;
 
 	if ((prop == NULL) || (strlen(prop) == 0) || (prop[0] != '/')) {
 		xml_rtn_msg(&msg, ERR_INVALID_BASEDIR);
@@ -686,7 +687,24 @@
 
 	while ((targ = tgt_node_next(targets_config, XML_ELEMENT_TARG,
 	    targ)) != NULL) {
-		count++;
+		/*
+		 * If the target does not have the "in-core" attribute, or
+		 * if it does have the attribute, but is set to "false" then
+		 * count the target.
+		 * Targets that are marked as in-core simply mean that some
+		 * other entity is storing the configuration data. Since that's
+		 * the case there's no trouble in change the base directory
+		 * because nothing will be lost.
+		 */
+		if ((tgt_find_attr_str(targ, XML_ELEMENT_INCORE, &val) ==
+		    False) ||
+		    ((val != NULL) && (strcmp(val, XML_VALUE_TRUE) != 0))) {
+			count++;
+		}
+		if (val) {
+			free(val);
+			val = NULL;
+		}
 	}
 
 	if (target_basedir == NULL) {
--- a/usr/src/cmd/iscsi/iscsitgtd/t10_sbc.c	Tue Dec 19 14:40:22 2006 -0800
+++ b/usr/src/cmd/iscsi/iscsitgtd/t10_sbc.c	Tue Dec 19 15:46:00 2006 -0800
@@ -75,6 +75,7 @@
 static char *sense_info_ctrl(char *buf);
 static scsi_cmd_table_t lba_table[];
 
+static long sbc_page_size;
 /*
  * []----
  * | sbc_init_common -- Initialize LU data which is common to all I_T_Ls
@@ -86,6 +87,8 @@
 	disk_params_t	*d;
 	tgt_node_t	*node	= lu->l_root;
 
+	sbc_page_size = sysconf(_SC_PAGESIZE);
+
 	if ((d = (disk_params_t *)calloc(1, sizeof (*d))) == NULL)
 		return (False);
 
@@ -690,6 +693,18 @@
 			return;
 
 		if (d->d_fast_write == False) {
+			uint64_t	sa;
+			size_t		len;
+
+			/*
+			 * msync requires the address to be page aligned.
+			 * That means we need to account for any alignment
+			 * loss in the len field and access the full page.
+			 */
+			sa = (uint64_t)(intptr_t)data & ~(sbc_page_size - 1);
+			len = (((size_t)data & (sbc_page_size - 1)) +
+			    data_len + sbc_page_size - 1) &
+			    ~(sbc_page_size -1);
 
 			/*
 			 * We only need to worry about sync'ing the blocks
@@ -697,7 +712,8 @@
 			 * enabled for AIO the file will be opened with F_SYNC
 			 * which performs the correct action.
 			 */
-			if (fsync(cmd->c_lu->l_common->l_fd) == -1) {
+			if (msync((char *)(intptr_t)sa, len, MS_SYNC) == -1) {
+				perror("msync");
 				spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0);
 				trans_send_complete(cmd, STATUS_CHECK);
 				return;
@@ -803,10 +819,19 @@
 		/*
 		 * Immediate bit is not set, so go ahead a flush things.
 		 */
-		if (fsync(cmd->c_lu->l_common->l_fd) != 0) {
-			spc_sense_create(cmd, KEY_MEDIUM_ERROR, 0);
-			trans_send_complete(cmd, STATUS_CHECK);
-			return;
+		if (cmd->c_lu->l_common->l_mmap == MAP_FAILED) {
+			if (fsync(cmd->c_lu->l_common->l_fd) != 0) {
+				spc_sense_create(cmd, KEY_MEDIUM_ERROR, 0);
+				trans_send_complete(cmd, STATUS_CHECK);
+				return;
+			}
+		} else {
+			if (msync(cmd->c_lu->l_common->l_mmap,
+			    cmd->c_lu->l_common->l_size, MS_SYNC) == -1) {
+				spc_sense_create(cmd, KEY_MEDIUM_ERROR, 0);
+				trans_send_complete(cmd, STATUS_CHECK);
+				return;
+			}
 		}
 	}
 	trans_send_complete(cmd, STATUS_GOOD);
@@ -1086,21 +1111,45 @@
 
 			/*
 			 * Immediately return a status of GOOD. If an error
-			 * occurs with the fsync the next command will pick
-			 * up an error.
+			 * occurs with the fsync/msync the next command will
+			 * pick up an error.
 			 */
 			trans_send_complete(cmd, STATUS_GOOD);
-			if (fsync(cmd->c_lu->l_common->l_fd) == -1) {
-				cmd->c_lu->l_status	= KEY_HARDWARE_ERROR;
-				cmd->c_lu->l_asc	= 0x00;
-				cmd->c_lu->l_ascq	= 0x00;
+			if (cmd->c_lu->l_common->l_mmap == MAP_FAILED) {
+				if (fsync(cmd->c_lu->l_common->l_fd) == -1) {
+					cmd->c_lu->l_status =
+					    KEY_HARDWARE_ERROR;
+					cmd->c_lu->l_asc = 0x00;
+					cmd->c_lu->l_ascq = 0x00;
+				}
+			} else {
+				if (msync(cmd->c_lu->l_common->l_mmap,
+				    cmd->c_lu->l_common->l_size, MS_SYNC) ==
+				    -1) {
+					cmd->c_lu->l_status =
+					    KEY_HARDWARE_ERROR;
+					cmd->c_lu->l_asc = 0x00;
+					cmd->c_lu->l_ascq = 0x00;
+				}
 			}
 		} else {
-			if (fsync(cmd->c_lu->l_common->l_fd) == -1) {
-				spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0);
-				trans_send_complete(cmd, STATUS_CHECK);
-			} else
-				trans_send_complete(cmd, STATUS_GOOD);
+			if (cmd->c_lu->l_common->l_mmap == MAP_FAILED) {
+				if (fsync(cmd->c_lu->l_common->l_fd) == -1) {
+					spc_sense_create(cmd,
+					    KEY_HARDWARE_ERROR, 0);
+					trans_send_complete(cmd, STATUS_CHECK);
+				} else
+					trans_send_complete(cmd, STATUS_GOOD);
+			} else {
+				if (msync(cmd->c_lu->l_common->l_mmap,
+				    cmd->c_lu->l_common->l_size, MS_SYNC) ==
+				    -1) {
+					spc_sense_create(cmd,
+					    KEY_HARDWARE_ERROR, 0);
+					trans_send_complete(cmd, STATUS_CHECK);
+				} else
+					trans_send_complete(cmd, STATUS_GOOD);
+			}
 		}
 	}
 }
--- a/usr/src/cmd/iscsi/iscsitgtd/t10_ssc.c	Tue Dec 19 14:40:22 2006 -0800
+++ b/usr/src/cmd/iscsi/iscsitgtd/t10_ssc.c	Tue Dec 19 15:46:00 2006 -0800
@@ -63,6 +63,8 @@
 static char *sense_dev_config(ssc_params_t *s, char *data);
 static char *sense_compression(ssc_params_t *s, char *data);
 
+static long ssc_page_size;
+
 /*
  * []----
  * | ssc_init_common -- initialize common information that all ITLs will use
@@ -74,6 +76,8 @@
 	ssc_params_t	*s;
 	ssc_obj_mark_t	mark;
 
+	ssc_page_size = sysconf(_SC_PAGESIZE);
+
 	if (lu->l_mmap == MAP_FAILED)
 		return (False);
 
@@ -474,13 +478,27 @@
 		return;
 
 	if (s->s_fast_write_ack == False) {
+		uint64_t	sa;
+		size_t		len;
+
+		/*
+		 * msync requires the address to be page aligned.
+		 * That means we need to account for any alignment
+		 * loss in the len field and access the full page.
+		 */
+		sa = (uint64_t)(intptr_t)data & ~(ssc_page_size - 1);
+		len = (((size_t)data & (ssc_page_size - 1)) +
+		    data_len + ssc_page_size - 1) &
+		    ~(ssc_page_size -1);
+
 		/*
 		 * We only need to worry about sync'ing the blocks
 		 * in the mmap case because if the fast cache isn't
 		 * enabled for AIO the file will be opened with F_SYNC
 		 * which performs the correct action.
 		 */
-		if (fsync(cmd->c_lu->l_common->l_fd) == -1) {
+		if (msync((char *)(intptr_t)sa, len, MS_SYNC) == -1) {
+			perror("msync");
 			spc_sense_create(cmd, KEY_HARDWARE_ERROR, 0);
 			trans_send_complete(cmd, STATUS_CHECK);
 			return;
--- a/usr/src/cmd/iscsi/iscsitgtd/target.h	Tue Dec 19 14:40:22 2006 -0800
+++ b/usr/src/cmd/iscsi/iscsitgtd/target.h	Tue Dec 19 15:46:00 2006 -0800
@@ -37,8 +37,9 @@
 extern "C" {
 #endif
 
-#define	DEFAULT_CONFIG_LOCATION	"/etc/iscsi/target_config.xml"
-#define	DEFAULT_TARGET_BASEDIR	"/iscsi_targets"
+#define	DEFAULT_CONFIG		"/etc/iscsi/"
+#define	DEFAULT_CONFIG_LOCATION	DEFAULT_CONFIG "target_config.xml"
+#define	DEFAULT_TARGET_BASEDIR	DEFAULT_CONFIG
 #define	DEFAULT_TARGET_LOG	"/tmp/target_log"
 
 /*
--- a/usr/src/lib/libiscsitgt/common/if_zfs.c	Tue Dec 19 14:40:22 2006 -0800
+++ b/usr/src/lib/libiscsitgt/common/if_zfs.c	Tue Dec 19 15:46:00 2006 -0800
@@ -58,11 +58,13 @@
 	if (strcmp(n->x_name, XML_ELEMENT_ERROR) == 0 &&
 	    tgt_find_value_int(n, XML_ELEMENT_CODE, &code) == True &&
 	    code == 1000) {
+		free(str);
 		tgt_node_free(n);
 		return (0);
 	}
 
 	errno = EINVAL;
+	free(str);
 	tgt_node_free(n);
 	return (-1);
 }
@@ -87,10 +89,12 @@
 	if (strcmp(n->x_name, XML_ELEMENT_ERROR) == 0 &&
 	    tgt_find_value_int(n, XML_ELEMENT_CODE, &code) == True &&
 	    code == 1000) {
+		free(str);
 		tgt_node_free(n);
 		return (0);
 	}
 
+	free(str);
 	tgt_node_free(n);
 	errno = EINVAL;
 	return (-1);
@@ -114,10 +118,12 @@
 	if (strcmp(n->x_name, XML_ELEMENT_ERROR) == 0 &&
 	    tgt_find_value_int(n, XML_ELEMENT_CODE, &code) == True &&
 	    code == 1000) {
+		free(str);
 		tgt_node_free(n);
 		return (1);
 	}
 
+	free(str);
 	tgt_node_free(n);
 	return (0);
 }
--- a/usr/src/lib/libiscsitgt/common/xml.c	Tue Dec 19 14:40:22 2006 -0800
+++ b/usr/src/lib/libiscsitgt/common/xml.c	Tue Dec 19 15:46:00 2006 -0800
@@ -457,6 +457,7 @@
 	if ((p == NULL) || (c == NULL))
 		return;
 
+	c->x_parent = p;
 	if (p->x_child == NULL)
 		p->x_child = c;
 	else {
@@ -683,10 +684,12 @@
 		return (NULL);
 	if (node_name(d, (xmlChar *)n->x_name) == False)
 		return (NULL);
-	if (node_value(d, (xmlChar *)n->x_value, True) == False)
+	if (n->x_value && (node_value(d, (xmlChar *)n->x_value, True) == False))
 		return (NULL);
 	for (c = n->x_child; c; c = c->x_sibling)
 		(void) tgt_node_add(d, tgt_node_dup(c));
+	for (c = n->x_attr; c; c = c->x_sibling)
+		(void) tgt_node_add_attr(d, tgt_node_dup(c));
 	return (d);
 }
 
--- a/usr/src/pkgdefs/SUNWiscsitgtu/preremove	Tue Dec 19 14:40:22 2006 -0800
+++ b/usr/src/pkgdefs/SUNWiscsitgtu/preremove	Tue Dec 19 15:46:00 2006 -0800
@@ -45,7 +45,7 @@
 # Check to see if the service is enabled and if so disable it.
 #
 
-SVCPROP=`svcprop -p general/enabled ${SERVICE}`
+SVCPROP=`svcprop -c -p general/enabled ${SERVICE}`
 
 if [ "${SVCPROP}" = "true" ]; then
     svcadm disable ${SERVICE}