diff --git a/main.c b/main.c
index 03240bf5..a79651cf 100644
--- a/main.c
+++ b/main.c
@@ -189,8 +189,50 @@ on_check_config(TCMUService1 *interface,
return TRUE;
}
+static gboolean
+on_media_change(TCMUService1 *interface,
+ GDBusMethodInvocation *invocation,
+ gchar *name,
+ guint64 size,
+ gchar *cfgstring,
+ gpointer user_data)
+{
+ struct tcmulib_context *ctx = user_data;
+ struct tcmu_device *dev = NULL;
+ char *reason = NULL;
+ int ret = 0;
+
+ dev = tcmulib_lookup_dev_by_tcmu_name(ctx, name);
+ if (!dev) {
+ reason = "failure no device";
+ goto exit;
+ }
+
+ tcmu_block_device(dev);
+ tcmu_flush_device(dev);
+
+ tcmu_set_control_str(dev, "dev_config", cfgstring);
+ tcmu_update_num_lbas(dev, size);
+ tcmu_set_dev_size(dev);
+
+ ret = tcmu_reopen_dev(dev, false, 0);
+ if (ret == 0)
+ reason = "success";
+
+ tcmu_dev_set_pending_ua(dev, TCMUR_UA_DEV_MEDIUM_CHANGED);
+ tcmu_unblock_device(dev);
+
+exit:
+ g_dbus_method_invocation_return_value(invocation,
+ g_variant_new("(is)", ret, reason ? : "unknown"));
+
+ return TRUE;
+}
+
static void
-dbus_export_handler(struct tcmur_handler *handler, GCallback check_config)
+dbus_export_handler(struct tcmulib_context *tcmulib_context,
+ struct tcmur_handler *handler, GCallback check_config,
+ GCallback media_change)
{
GDBusObjectSkeleton *object;
char obj_name[128];
@@ -205,6 +247,10 @@ dbus_export_handler(struct tcmur_handler *handler, GCallback check_config)
"handle-check-config",
check_config,
handler); /* user_data */
+ g_signal_connect(interface,
+ "handle-media-change",
+ media_change,
+ tcmulib_context);
tcmuservice1_set_config_desc(interface, handler->cfg_desc);
g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object));
g_object_unref(object);
@@ -216,12 +262,14 @@ static void dbus_bus_acquired(GDBusConnection *connection,
{
struct tcmur_handler **handler;
- tcmu_dbg("bus %s acquired\n", name);
+ tcmu_dbg("bus %s acquired %p\n", name, user_data);
manager = g_dbus_object_manager_server_new("/org/kernel/TCMUService1");
darray_foreach(handler, g_runner_handlers) {
- dbus_export_handler(*handler, G_CALLBACK(on_check_config));
+ dbus_export_handler(user_data, *handler,
+ G_CALLBACK(on_check_config),
+ G_CALLBACK(on_media_change));
}
g_dbus_object_manager_server_set_connection(manager, connection);
@@ -917,7 +965,7 @@ int main(int argc, char **argv)
dbus_bus_acquired,
dbus_name_acquired, // name acquired
dbus_name_lost, // name lost
- NULL, // user data
+ tcmulib_context, // user data
NULL // user date free func
);
diff --git a/tcmu-handler.xml b/tcmu-handler.xml
index 933d671c..a338758b 100644
--- a/tcmu-handler.xml
+++ b/tcmu-handler.xml
@@ -16,6 +16,13 @@ that the configstring is valid before the device has been created.
+
+
+
+
+
+
+
diff --git a/tcmur_device.c b/tcmur_device.c
index 69c77099..c95154dd 100644
--- a/tcmur_device.c
+++ b/tcmur_device.c
@@ -426,6 +426,10 @@ int tcmu_dev_handle_pending_ua(struct tcmu_device *dev, struct tcmulib_cmd *cmd)
/* Device capacity has changed */
tcmu_set_sense_data(cmd->sense_buf, UNIT_ATTENTION, 0x2A09);
break;
+ case TCMUR_UA_DEV_MEDIUM_CHANGED:
+ /* medium changed */
+ tcmu_set_sense_data(cmd->sense_buf, UNIT_ATTENTION, 0x2800);
+ break;
default:
tcmu_dev_err(dev, "Unhandled UA %d\n", ua);
goto unlock;
diff --git a/tcmur_device.h b/tcmur_device.h
index 27685a7d..f72af914 100644
--- a/tcmur_device.h
+++ b/tcmur_device.h
@@ -22,6 +22,7 @@
#define TCMUR_DEV_FLAG_STOPPED (1 << 4)
#define TCMUR_UA_DEV_SIZE_CHANGED 0
+#define TCMUR_UA_DEV_MEDIUM_CHANGED 1
enum {
TMCUR_DEV_FAILOVER_ALL_ACTIVE,