[PATCH 13/13] target: Add upcall to save aptpl state

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently we write APTPL state to /var/target/pr ourself. It's
preferable to avoid this if possible, by relying on a user helper
to save the state for us. But if it's not present, still do it the
old way for backwards-compatibility.

Signed-off-by: Andy Grover <agrover@xxxxxxxxxx>
---
 drivers/target/target_core_pr.c |   48 ++++++++++++++++++++++++++++++++++++--
 1 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index ac34401..c719bdf 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -28,6 +28,7 @@
 #include <linux/spinlock.h>
 #include <linux/list.h>
 #include <linux/file.h>
+#include <linux/kmod.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <asm/unaligned.h>
@@ -1916,7 +1917,33 @@ out:
 	return ret;
 }
 
-static int __core_scsi3_write_aptpl_to_file(
+static char target_upcall_path[] = "/sbin/target_notify";
+
+static int core_scsi3_aptpl_upcall(struct se_device *dev, unsigned char *buf)
+{
+        int ret;
+        char *argv[2], *envp[4];
+	/* space for wwn + 'APTPL=' + '\0' */
+	char aptpl_env[INQUIRY_VPD_SERIAL_LEN+7];
+
+	snprintf(aptpl_env, sizeof(aptpl_env), "APTPL=%s", dev->t10_wwn.unit_serial);
+
+        argv[0] = target_upcall_path;
+        argv[1] = NULL;
+
+        envp[0] = "HOME=/";
+        envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+        envp[2] = aptpl_env;
+        envp[3] = NULL;
+
+        ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
+        if (ret < 0)
+		pr_debug("target: upcall failed\n");
+
+	return ret;
+}
+
+static int core_scsi3_write_aptpl_to_file(
 	struct se_device *dev,
 	unsigned char *buf)
 {
@@ -1954,6 +1981,21 @@ static int __core_scsi3_write_aptpl_to_file(
 	return ret ? -EIO : 0;
 }
 
+static int core_scsi3_save_aptpl(struct se_device *dev, unsigned char *buf)
+{
+	int ret;
+
+	/*
+	 * Assume if user helper exists, it saved aptpl state.
+	 * Otherwise, write it to the fs ourselves.
+	 */
+	ret = core_scsi3_aptpl_upcall(dev, buf);
+	if (ret < 0)
+		ret = core_scsi3_write_aptpl_to_file(dev, buf);
+
+	return ret;
+}
+
 /*
  * Clear the APTPL metadata if APTPL has been disabled, otherwise
  * write out the updated metadata to struct file for this SCSI device.
@@ -1965,7 +2007,7 @@ static int core_scsi3_update_and_write_aptpl(struct se_device *dev, bool aptpl)
 	if (!aptpl) {
 		char *null_buf = "No Registrations or Reservations\n";
 
-		ret = __core_scsi3_write_aptpl_to_file(dev, null_buf);
+		ret = core_scsi3_save_aptpl(dev, null_buf);
 		dev->t10_pr.pr_aptpl_active = 0;
 		pr_debug("SPC-3 PR: Set APTPL Bit Deactivated\n");
 	} else {
@@ -1982,7 +2024,7 @@ static int core_scsi3_update_and_write_aptpl(struct se_device *dev, bool aptpl)
 			return ret;
 		}
 
-		ret = __core_scsi3_write_aptpl_to_file(dev, buf);
+		ret = core_scsi3_save_aptpl(dev, buf);
 		if (ret < 0) {
 			pr_err("SPC-3 PR: Could not update APTPL\n");
 		} else {
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux