From ac3447ab680ef5319717fc6b85a4c5b22e652e5e Mon Sep 17 00:00:00 2001 From: Chris Leech Date: Fri, 7 Dec 2012 17:01:42 -0800 Subject: 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 8f9de05..323d0a8 100644 --- a/usr/iscsiadm.c +++ b/usr/iscsiadm.c @@ -111,6 +111,7 @@ 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, 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:u"; @@ -131,6 +132,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 [ -l ]\n\ iscsiadm -m host [ -P printlevel ] [ -H hostno|MAC ] [ -C chap [ -o operation ] [ -v chap_tbl_idx ] ]\n\ +iscsiadm --newroot switch_root_path\n\ iscsiadm -k priority\n"); } exit(status); @@ -251,6 +253,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 @@ -2397,6 +2415,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; @@ -2433,6 +2452,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) { @@ -2579,6 +2604,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.7.11.7