--- /dev/null
+From e74f511ba862195d909bba90091fd84bd7904914 Mon Sep 17 00:00:00 2001
+From: Chris Leech <cleech@redhat.com>
+Date: Wed, 2 Jan 2013 14:45:05 -0800
+Subject: iscsiuio IPC newroot command
+
+---
+ usr/mgmt_ipc.c | 11 +++++++++++
+ usr/transport.c | 1 +
+ usr/transport.h | 1 +
+ usr/uip_mgmt_ipc.c | 14 ++++++++++++++
+ usr/uip_mgmt_ipc.h | 5 +++++
+ 5 files changed, 32 insertions(+)
+
+diff --git a/usr/mgmt_ipc.c b/usr/mgmt_ipc.c
+index 5cb7143..a8f8473 100644
+--- a/usr/mgmt_ipc.c
++++ b/usr/mgmt_ipc.c
+@@ -36,6 +36,7 @@
+ #include "sysdeps.h"
+ #include "iscsi_ipc.h"
+ #include "iscsi_err.h"
++#include "iscsi_sysfs.h"
+
+ #define PEERUSER_MAX 64
+ #define EXTMSG_MAX (64 * 1024)
+@@ -229,8 +230,18 @@ static int
+ mgmt_ipc_newroot(queue_task_t *qtask)
+ {
+ char *newroot = qtask->req.u.newroot.path;
++ struct iscsi_transport *t;
++
+ if (chdir(newroot) || chroot(".") || chdir("/"))
+ return ISCSI_ERR;
++
++ /* if a registered transport has a separate userspace process,
++ * notify it of the root change as well */
++ list_for_each_entry(t, &transports, list) {
++ if (t->template->newroot)
++ t->template->newroot(t, newroot);
++ }
++
+ mgmt_ipc_write_rsp(qtask, ISCSI_SUCCESS);
+ return ISCSI_SUCCESS;
+ }
+diff --git a/usr/transport.c b/usr/transport.c
+index 10212af..02ad717 100644
+--- a/usr/transport.c
++++ b/usr/transport.c
+@@ -81,6 +81,7 @@ struct iscsi_transport_template bnx2i = {
+ .ep_poll = ktransport_ep_poll,
+ .ep_disconnect = ktransport_ep_disconnect,
+ .set_net_config = uip_broadcast_params,
++ .newroot = uip_broadcast_newroot,
+ };
+
+ struct iscsi_transport_template be2iscsi = {
+diff --git a/usr/transport.h b/usr/transport.h
+index 5dcf872..eb3a946 100644
+--- a/usr/transport.h
++++ b/usr/transport.h
+@@ -38,6 +38,7 @@ struct iscsi_transport_template {
+ int (*set_net_config) (struct iscsi_transport *t,
+ struct iface_rec *iface,
+ struct iscsi_session *session);
++ void (*newroot) (struct iscsi_transport *t, char *path);
+ };
+
+ /* represents data path provider */
+diff --git a/usr/uip_mgmt_ipc.c b/usr/uip_mgmt_ipc.c
+index 73b1632..9fa5398 100644
+--- a/usr/uip_mgmt_ipc.c
++++ b/usr/uip_mgmt_ipc.c
+@@ -39,3 +39,17 @@ int uip_broadcast_params(struct iscsi_transport *t,
+ sizeof(iscsid_uip_broadcast_header_t) +
+ sizeof(*iface));
+ }
++
++int uip_broadcast_newroot(struct iscsi_transport *t, char *newroot)
++{
++ struct iscsid_uip_broadcast broadcast;
++
++ memset(&broadcast, 0, sizeof(broadcast));
++
++ broadcast.header.command = ISCSID_UIP_NEWROOT;
++ strncpy(broadcast.u.newroot.path, newroot, PATH_MAX);
++
++ return uip_broadcast(&broadcast,
++ sizeof(iscsid_uip_broadcast_header_t) +
++ PATH_MAX + 1);
++}
+diff --git a/usr/uip_mgmt_ipc.h b/usr/uip_mgmt_ipc.h
+index 3859688..9de88c2 100644
+--- a/usr/uip_mgmt_ipc.h
++++ b/usr/uip_mgmt_ipc.h
+@@ -29,6 +29,7 @@
+ typedef enum iscsid_uip_cmd {
+ ISCSID_UIP_IPC_UNKNOWN = 0,
+ ISCSID_UIP_IPC_GET_IFACE = 1,
++ ISCSID_UIP_NEWROOT = 2,
+
+ __ISCSID_UIP_IPC_MAX_COMMAND
+ } iscsid_uip_cmd_e;
+@@ -47,6 +48,9 @@ typedef struct iscsid_uip_broadcast {
+ struct ipc_broadcast_iface_rec {
+ struct iface_rec rec;
+ } iface_rec;
++ struct ipc_broadcast_newroot {
++ char path[PATH_MAX + 1];
++ } newroot;
+ } u;
+ } iscsid_uip_broadcast_t;
+
+@@ -69,5 +73,6 @@ extern int uip_broadcast_params(struct iscsi_transport *t,
+ struct iface_rec *iface,
+ struct iscsi_session *session);
+
++extern int uip_broadcast_newroot(struct iscsi_transport *t, char *path);
+
+ #endif /* UIP_MGMT_IPC_H */
+--
+1.7.11.7
+