From e5d7c7070358a5db8b849c8c5886e67881fe8906 Mon Sep 17 00:00:00 2001 From: Chris Leech Date: Fri, 7 Dec 2012 17:01:42 -0800 Subject: [PATCH 47/47] iscsiadm, iscsid: newroot command to survive switch_root 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. Signed-off-by: Chris Leech --- usr/iscsiadm.c | 30 ++++++++++++++++++++++++++++++ usr/mgmt_ipc.c | 11 +++++++++++ usr/mgmt_ipc.h | 6 +++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c index da0a3ec..af6d607 100644 --- a/usr/iscsiadm.c +++ b/usr/iscsiadm.c @@ -117,6 +117,7 @@ static struct option const long_options[] = {"interval", required_argument, NULL, 'i'}, {"flashnode_idx", optional_argument, NULL, 'x'}, {"portal_type", optional_argument, NULL, 'A'}, + {"newroot", required_argument, NULL, 0}, {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:ux:A:"; @@ -137,6 +138,7 @@ iscsiadm -m session [ -hV ] [ -d debug_level ] [ -P printlevel] [ -r sessionid 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\ iscsiadm -m fw [ -d debug_level ] [ -l ]\n\ 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\ +iscsiadm --newroot switch_root_path\n\ iscsiadm -k priority\n"); } exit(status); @@ -278,6 +280,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 @@ -2800,6 +2818,7 @@ main(int argc, char **argv) { char *ip = NULL, *name = NULL, *value = NULL; char *targetname = NULL, *group_session_mgmt_mode = NULL; + char *newroot = NULL; int ch, longindex, mode=-1, port=-1, do_login=0, do_rescan=0; int rc=0, sid=-1, op=OP_NOOP, type=-1, do_logout=0, do_stats=0; int do_login_all=0, do_logout_all=0, info_level=-1, num_ifaces = 0; @@ -2837,6 +2856,12 @@ main(int argc, char **argv) while ((ch = getopt_long(argc, argv, short_options, long_options, &longindex)) >= 0) { switch (ch) { + case 0: + if (long_options[longindex].flag != 0) + break; + if (!strcmp(long_options[longindex].name, "newroot")) + newroot = optarg; + break; case 'k': killiscsid = atoi(optarg); if (killiscsid < 0) { @@ -2989,6 +3014,11 @@ main(int argc, char **argv) goto free_ifaces; } + if (newroot) { + do_newroot(newroot); + goto free_ifaces; + } + if (mode < 0) usage(ISCSI_ERR_INVAL); diff --git a/usr/mgmt_ipc.c b/usr/mgmt_ipc.c index 87bd346..5cb7143 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.8.1.4