c2d5d21
From e5d7c7070358a5db8b849c8c5886e67881fe8906 Mon Sep 17 00:00:00 2001
6bbb925
From: Chris Leech <cleech@redhat.com>
6bbb925
Date: Fri, 7 Dec 2012 17:01:42 -0800
c2d5d21
Subject: [PATCH 47/47] iscsiadm, iscsid: newroot command to survive
c2d5d21
 switch_root
6bbb925
6bbb925
When started from initramfs, iscsid needs to be able to chroot itself
6bbb925
to the runtime filesystem before the switch_root occurs.  In the
6bbb925
initramfs "iscsiadm --newroot {root fs mount before switch}" should be
6bbb925
called before the switch_root.
6bbb925
6bbb925
Signed-off-by: Chris Leech <cleech@redhat.com>
6bbb925
---
6bbb925
 usr/iscsiadm.c | 30 ++++++++++++++++++++++++++++++
6bbb925
 usr/mgmt_ipc.c | 11 +++++++++++
6bbb925
 usr/mgmt_ipc.h |  6 +++++-
6bbb925
 3 files changed, 46 insertions(+), 1 deletion(-)
6bbb925
6bbb925
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
c2d5d21
index da0a3ec..af6d607 100644
6bbb925
--- a/usr/iscsiadm.c
6bbb925
+++ b/usr/iscsiadm.c
c2d5d21
@@ -117,6 +117,7 @@ static struct option const long_options[] =
6bbb925
 	{"interval", required_argument, NULL, 'i'},
c2d5d21
 	{"flashnode_idx", optional_argument, NULL, 'x'},
c2d5d21
 	{"portal_type", optional_argument, NULL, 'A'},
6bbb925
+	{"newroot", required_argument, NULL, 0},
6bbb925
 	{NULL, 0, NULL, 0},
6bbb925
 };
c2d5d21
 static char *short_options = "RlDVhm:a:b:c:C:p:P:T:H:i:I:U:k:L:d:r:n:v:o:sSt:ux:A:";
c2d5d21
@@ -137,6 +138,7 @@ iscsiadm -m session [ -hV ] [ -d debug_level ] [ -P  printlevel] [ -r sessionid
6bbb925
 iscsiadm -m iface [ -hV ] [ -d debug_level ] [ -P printlevel ] [ -I ifacename | -H hostno|MAC ] [ [ -o  operation  ] [ -n name ] [ -v value ] ] [ -C ping [ -a ip ] [ -b packetsize ] [ -c count ] [ -i interval ] ]\n\
c2d5d21
 iscsiadm -m fw [ -d debug_level ] [ -l ]\n\
c2d5d21
 iscsiadm -m host [ -P printlevel ] [ -H hostno|MAC ] [ [ -C chap [ -o operation ] [ -v chap_tbl_idx ] ] | [ -C flashnode [ -o operation ] [ -A portal_type ] [ -x flashnode_idx ] [ -n name ] [ -v value ] ] ]\n\
6bbb925
+iscsiadm --newroot switch_root_path\n\
6bbb925
 iscsiadm -k priority\n");
6bbb925
 	}
6bbb925
 	exit(status);
c2d5d21
@@ -278,6 +280,22 @@ static void kill_iscsid(int priority)
6bbb925
 	}
6bbb925
 }
6bbb925
 
6bbb925
+static void do_newroot(char *newroot)
6bbb925
+{
6bbb925
+	iscsiadm_req_t req;
6bbb925
+	iscsiadm_rsp_t rsp;
6bbb925
+	int rc;
6bbb925
+
6bbb925
+	memset(&req, 0, sizeof(req));
6bbb925
+	req.command = MGMT_IPC_NEWROOT;
6bbb925
+	strncpy(req.u.newroot.path, newroot, PATH_MAX);
6bbb925
+	rc = iscsid_exec_req(&req, &rsp, 0);
6bbb925
+	if (rc) {
6bbb925
+		iscsi_err_print_msg(rc);
6bbb925
+		log_error("Could not send NEWROOT command");
6bbb925
+	}
6bbb925
+}
6bbb925
+
6bbb925
 /*
6bbb925
  * TODO: we can display how the ifaces are related to node records.
6bbb925
  * And we can add a scsi_host mode which would display how
c2d5d21
@@ -2800,6 +2818,7 @@ main(int argc, char **argv)
6bbb925
 {
6bbb925
 	char *ip = NULL, *name = NULL, *value = NULL;
6bbb925
 	char *targetname = NULL, *group_session_mgmt_mode = NULL;
6bbb925
+	char *newroot = NULL;
6bbb925
 	int ch, longindex, mode=-1, port=-1, do_login=0, do_rescan=0;
6bbb925
 	int rc=0, sid=-1, op=OP_NOOP, type=-1, do_logout=0, do_stats=0;
6bbb925
 	int do_login_all=0, do_logout_all=0, info_level=-1, num_ifaces = 0;
c2d5d21
@@ -2837,6 +2856,12 @@ main(int argc, char **argv)
6bbb925
 	while ((ch = getopt_long(argc, argv, short_options,
6bbb925
 				 long_options, &longindex)) >= 0) {
6bbb925
 		switch (ch) {
6bbb925
+		case 0:
6bbb925
+			if (long_options[longindex].flag != 0)
6bbb925
+				break;
6bbb925
+			if (!strcmp(long_options[longindex].name, "newroot"))
6bbb925
+				newroot = optarg;
6bbb925
+			break;
6bbb925
 		case 'k':
6bbb925
 			killiscsid = atoi(optarg);
6bbb925
 			if (killiscsid < 0) {
c2d5d21
@@ -2989,6 +3014,11 @@ main(int argc, char **argv)
6bbb925
 		goto free_ifaces;
6bbb925
 	}
6bbb925
 
6bbb925
+	if (newroot) {
6bbb925
+		do_newroot(newroot);
6bbb925
+		goto free_ifaces;
6bbb925
+	}
6bbb925
+
6bbb925
 	if (mode < 0)
6bbb925
 		usage(ISCSI_ERR_INVAL);
6bbb925
 
6bbb925
diff --git a/usr/mgmt_ipc.c b/usr/mgmt_ipc.c
6bbb925
index 87bd346..5cb7143 100644
6bbb925
--- a/usr/mgmt_ipc.c
6bbb925
+++ b/usr/mgmt_ipc.c
6bbb925
@@ -226,6 +226,16 @@ mgmt_ipc_immediate_stop(queue_task_t *qtask)
6bbb925
 }
6bbb925
 
6bbb925
 static int
6bbb925
+mgmt_ipc_newroot(queue_task_t *qtask)
6bbb925
+{
6bbb925
+	char *newroot = qtask->req.u.newroot.path;
6bbb925
+	if (chdir(newroot) || chroot(".") || chdir("/"))
6bbb925
+		return ISCSI_ERR;
6bbb925
+	mgmt_ipc_write_rsp(qtask, ISCSI_SUCCESS);
6bbb925
+	return ISCSI_SUCCESS;
6bbb925
+}
6bbb925
+
6bbb925
+static int
6bbb925
 mgmt_ipc_conn_remove(queue_task_t *qtask)
6bbb925
 {
6bbb925
 	return ISCSI_ERR;
6bbb925
@@ -534,6 +544,7 @@ static mgmt_ipc_fn_t *	mgmt_ipc_functions[__MGMT_IPC_MAX_COMMAND] = {
6bbb925
 [MGMT_IPC_NOTIFY_DEL_NODE]	= mgmt_ipc_notify_del_node,
6bbb925
 [MGMT_IPC_NOTIFY_ADD_PORTAL]	= mgmt_ipc_notify_add_portal,
6bbb925
 [MGMT_IPC_NOTIFY_DEL_PORTAL]	= mgmt_ipc_notify_del_portal,
6bbb925
+[MGMT_IPC_NEWROOT]		= mgmt_ipc_newroot,
6bbb925
 };
6bbb925
 
6bbb925
 void mgmt_ipc_handle(int accept_fd)
6bbb925
diff --git a/usr/mgmt_ipc.h b/usr/mgmt_ipc.h
6bbb925
index 55972ed..102ffff 100644
6bbb925
--- a/usr/mgmt_ipc.h
6bbb925
+++ b/usr/mgmt_ipc.h
6bbb925
@@ -22,6 +22,7 @@
6bbb925
 #include "types.h"
6bbb925
 #include "iscsi_if.h"
6bbb925
 #include "config.h"
6bbb925
+#include "limits.h"
6bbb925
 
6bbb925
 #define ISCSIADM_NAMESPACE	"ISCSIADM_ABSTRACT_NAMESPACE"
6bbb925
 #define PEERUSER_MAX		64
6bbb925
@@ -46,6 +47,7 @@ typedef enum iscsiadm_cmd {
6bbb925
 	MGMT_IPC_NOTIFY_DEL_NODE	= 17,
6bbb925
 	MGMT_IPC_NOTIFY_ADD_PORTAL	= 18,
6bbb925
 	MGMT_IPC_NOTIFY_DEL_PORTAL	= 19,
6bbb925
+	MGMT_IPC_NEWROOT		= 20,
6bbb925
 
6bbb925
 	__MGMT_IPC_MAX_COMMAND
6bbb925
 } iscsiadm_cmd_e;
6bbb925
@@ -75,8 +77,10 @@ typedef struct iscsiadm_req {
6bbb925
 			int param;
6bbb925
 			/* TODO: make this variable len to support */
6bbb925
 			char value[IFNAMSIZ + 1];
6bbb925
-
6bbb925
 		} set_host_param;
6bbb925
+		struct ipc_msg_newroot {
6bbb925
+			char path[PATH_MAX + 1];
6bbb925
+		} newroot;
6bbb925
 	} u;
6bbb925
 } iscsiadm_req_t;
6bbb925
 
6bbb925
-- 
c2d5d21
1.8.1.4
6bbb925