When started from initramfs, iscsid needs to be able to chroot itself
to the runtime filesystem before the switch_root occurs.  In the
initramfs "iscsiadm --newroot {root fs mount before switch}" should be
called before the switch_root.
---
 usr/iscsiadm.c | 30 +++++++++++++++++++++++++++++-
 usr/mgmt_ipc.c | 11 +++++++++++
 usr/mgmt_ipc.h |  6 +++++-
 3 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index 8f9de05..7b601b3 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -111,9 +111,10 @@ static struct option const long_options[] =
        {"packetsize", required_argument, NULL, 'b'},
        {"count", required_argument, NULL, 'c'},
        {"interval", required_argument, NULL, 'i'},
+       {"newroot", required_argument, NULL, 'N'},
        {NULL, 0, NULL, 0},
 };
-static char *short_options = 
"RlDVhm:a:b:c:C:p:P:T:H:i:I:U:k:L:d:r:n:v:o:sSt:u";
+static char *short_options = 
"RlDVhm:a:b:c:C:p:P:T:H:i:I:U:k:L:d:r:n:v:o:sSt:uN:";
 
 static void usage(int status)
 {
@@ -251,6 +252,22 @@ static void kill_iscsid(int priority)
        }
 }
 
+static void do_newroot(char *newroot)
+{
+       iscsiadm_req_t req;
+       iscsiadm_rsp_t rsp;
+       int rc;
+
+       memset(&req, 0, sizeof(req));
+       req.command = MGMT_IPC_NEWROOT;
+       strncpy(req.u.newroot.path, newroot, PATH_MAX);
+       rc = iscsid_exec_req(&req, &rsp, 0);
+       if (rc) {
+               iscsi_err_print_msg(rc);
+               log_error("Could not send NEWROOT command");
+       }
+}
+
 /*
  * TODO: we can display how the ifaces are related to node records.
  * And we can add a scsi_host mode which would display how
@@ -2411,6 +2428,7 @@ main(int argc, char **argv)
        uint32_t host_no = -1;
        struct user_param *param;
        struct list_head params;
+       char *newroot = NULL;
 
        INIT_LIST_HEAD(&params);
        INIT_LIST_HEAD(&ifaces);
@@ -2433,6 +2451,9 @@ main(int argc, char **argv)
        while ((ch = getopt_long(argc, argv, short_options,
                                 long_options, &longindex)) >= 0) {
                switch (ch) {
+               case 'N':
+                       newroot = strndup(optarg, PATH_MAX);
+                       break;
                case 'k':
                        killiscsid = atoi(optarg);
                        if (killiscsid < 0) {
@@ -2579,6 +2600,13 @@ main(int argc, char **argv)
                goto free_ifaces;
        }
 
+       if (newroot) {
+               do_newroot(newroot);
+               free(newroot);
+               newroot = NULL;
+               goto free_ifaces;
+       }
+
        if (mode < 0)
                usage(ISCSI_ERR_INVAL);
 
diff --git a/usr/mgmt_ipc.c b/usr/mgmt_ipc.c
index f34f688..b4170ce 100644
--- a/usr/mgmt_ipc.c
+++ b/usr/mgmt_ipc.c
@@ -226,6 +226,16 @@ mgmt_ipc_immediate_stop(queue_task_t *qtask)
 }
 
 static int
+mgmt_ipc_newroot(queue_task_t *qtask)
+{
+       char *newroot = qtask->req.u.newroot.path;
+       if (chdir(newroot) || chroot(".") || chdir("/"))
+               return ISCSI_ERR;
+       mgmt_ipc_write_rsp(qtask, ISCSI_SUCCESS);
+       return ISCSI_SUCCESS;
+}
+
+static int
 mgmt_ipc_conn_remove(queue_task_t *qtask)
 {
        return ISCSI_ERR;
@@ -534,6 +544,7 @@ static mgmt_ipc_fn_t *      
mgmt_ipc_functions[__MGMT_IPC_MAX_COMMAND] = {
 [MGMT_IPC_NOTIFY_DEL_NODE]     = mgmt_ipc_notify_del_node,
 [MGMT_IPC_NOTIFY_ADD_PORTAL]   = mgmt_ipc_notify_add_portal,
 [MGMT_IPC_NOTIFY_DEL_PORTAL]   = mgmt_ipc_notify_del_portal,
+[MGMT_IPC_NEWROOT]             = mgmt_ipc_newroot,
 };
 
 void mgmt_ipc_handle(int accept_fd)
diff --git a/usr/mgmt_ipc.h b/usr/mgmt_ipc.h
index 55972ed..102ffff 100644
--- a/usr/mgmt_ipc.h
+++ b/usr/mgmt_ipc.h
@@ -22,6 +22,7 @@
 #include "types.h"
 #include "iscsi_if.h"
 #include "config.h"
+#include "limits.h"
 
 #define ISCSIADM_NAMESPACE     "ISCSIADM_ABSTRACT_NAMESPACE"
 #define PEERUSER_MAX           64
@@ -46,6 +47,7 @@ typedef enum iscsiadm_cmd {
        MGMT_IPC_NOTIFY_DEL_NODE        = 17,
        MGMT_IPC_NOTIFY_ADD_PORTAL      = 18,
        MGMT_IPC_NOTIFY_DEL_PORTAL      = 19,
+       MGMT_IPC_NEWROOT                = 20,
 
        __MGMT_IPC_MAX_COMMAND
 } iscsiadm_cmd_e;
@@ -75,8 +77,10 @@ typedef struct iscsiadm_req {
                        int param;
                        /* TODO: make this variable len to support */
                        char value[IFNAMSIZ + 1];
-
                } set_host_param;
+               struct ipc_msg_newroot {
+                       char path[PATH_MAX + 1];
+               } newroot;
        } u;
 } iscsiadm_req_t;
 
-- 
1.7.11.7

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To post to this group, send email to open-iscsi@googlegroups.com.
To unsubscribe from this group, send email to 
open-iscsi+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/open-iscsi?hl=en.

Reply via email to