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,