summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2010-10-08 10:11:34 -0400
committerDavid Zeuthen <davidz@redhat.com>2010-10-08 10:11:34 -0400
commitd1a9155cf6dd7818b64d586c727555eab4a62ec8 (patch)
tree77af4a62704dc869be81103729ce7ba3c2279d75
parent68f743407bc7ba627add70b0cd3b103a8f813690 (diff)
Add state STC_ITEM_STATE_DEFUNCT and show it for supported types
Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r--data/79-stc.rules18
-rw-r--r--data/Makefile.am6
-rw-r--r--doc/stc.conf.xml9
-rw-r--r--doc/stc.xml4
-rw-r--r--stc/stc.c3
-rw-r--r--stc/stcenums.h22
-rw-r--r--stc/stcitem.c529
-rw-r--r--stc/stcmonitor.c5
-rw-r--r--stc/stcmount.h2
-rw-r--r--stc/stcmountmonitor.c38
-rw-r--r--stc/stcmountmonitor.h2
11 files changed, 435 insertions, 203 deletions
diff --git a/data/79-stc.rules b/data/79-stc.rules
new file mode 100644
index 0000000..0911c16
--- /dev/null
+++ b/data/79-stc.rules
@@ -0,0 +1,18 @@
+
+# stc udev rules
+#
+
+# Unfortunately mdadm sets the wrong MD_UUID and MD_NAME if all
+# components are yanked. So save the original values
+#
+# (TODO: want this fix in the mdadm udev rules)
+#
+SUBSYSTEM=="block", KERNEL=="md*", GOTO="stc_is_md"
+GOTO="stc_md_end"
+LABEL=stc_is_md"
+IMPORT{db}="STC_ORIG_MD_UUID"
+IMPORT{db}="STC_ORIG_MD_NAME"
+ENV{STC_ORIG_MD_UUID}=="", ENV{MD_UUID}!="", ENV{STC_ORIG_MD_UUID}="$env{MD_UUID}"
+ENV{STC_ORIG_MD_NAME}=="", ENV{MD_NAME}!="", ENV{STC_ORIG_MD_NAME}="$env{MD_NAME}"
+LABEL=stc_md_end"
+
diff --git a/data/Makefile.am b/data/Makefile.am
index ab1066b..94f1a8a 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -9,11 +9,17 @@ config_DATA = stc.conf
# ----------------------------------------------------------------------------------------------------
+udevrulesdir = /lib/udev/rules.d
+udevrules_DATA = 79-stc.rules
+
+# ----------------------------------------------------------------------------------------------------
+
CLEANFILES =
EXTRA_DIST = \
$(profile_SCRIPTS) \
stc.conf.in \
+ $(udevrules_DATA) \
stc-1.pc.in \
$(NULL)
diff --git a/doc/stc.conf.xml b/doc/stc.conf.xml
index 145fbd1..d749f6c 100644
--- a/doc/stc.conf.xml
+++ b/doc/stc.conf.xml
@@ -202,11 +202,10 @@ FilesystemOptions=umask=0022,noatime
<title>Luks Items</title>
<para>
Items of type <literal>Luks</literal> are used to unlock an
- encrypted device. The keys <literal>Device</literal> and
- <literal>UUID</literal> can be used to refer to the device. The
- option <literal>LuksPassphrase</literal> is
- <emphasis>optional</emphasis> and if set, contains the passphrase
- used to unlock the device. If the
+ encrypted device. The key <literal>UUID</literal> can be used to
+ refer to the device. The option <literal>LuksPassphrase</literal>
+ is <emphasis>optional</emphasis> and if set, contains the
+ passphrase used to unlock the device. If the
<literal>LuksPassphrase</literal> option is not set, then the user
is asked for the passphrase when starting the device.
</para>
diff --git a/doc/stc.xml b/doc/stc.xml
index b4db292..b836b9d 100644
--- a/doc/stc.xml
+++ b/doc/stc.xml
@@ -151,8 +151,8 @@
<term><literal>started</literal></term>
<listitem>
<para>
- The device the item is referencing has started and is
- running.
+ The device the item is referencing has been started and is
+ now running.
</para>
</listitem>
</varlistentry>
diff --git a/stc/stc.c b/stc/stc.c
index 91e6f2d..4e4c499 100644
--- a/stc/stc.c
+++ b/stc/stc.c
@@ -894,7 +894,8 @@ handle_command_start_stop (gint *argc,
}
else
{
- if (state == STC_ITEM_STATE_STARTED)
+ if (state == STC_ITEM_STATE_STARTED ||
+ state == STC_ITEM_STATE_DEFUNCT)
{
g_print ("%s \n", stc_item_get_id (item));
}
diff --git a/stc/stcenums.h b/stc/stcenums.h
index 627ff24..5737310 100644
--- a/stc/stcenums.h
+++ b/stc/stcenums.h
@@ -69,10 +69,23 @@ typedef enum
/**
* StcItemState:
- * @STC_ITEM_STATE_NOT_STARTED: The object or one of its dependencies has not been started and cannot be started at this time.
- * @STC_ITEM_STATE_CAN_START_DEGRADED: Like %STC_ITEM_STATE_CAN_START but the object (or one of its dependencies) will be started degraded.
- * @STC_ITEM_STATE_CAN_START: The object is not currently running but it is possible to start it.
- * @STC_ITEM_STATE_STARTED: The object has been started.
+ * @STC_ITEM_STATE_NOT_STARTED: The device the item (or one of its
+ * dependencies) is referencing has not
+ * been started. Additionally there is no
+ * way to currently start it.
+ * @STC_ITEM_STATE_CAN_START_DEGRADED: The device the item (or one of
+ * its dependencies) is
+ * referencing can be started in a
+ * degraded mode.
+ * @STC_ITEM_STATE_CAN_START: The device the item (or one of its
+ * dependencies) is referencing can be
+ * started.
+ * @STC_ITEM_STATE_STARTED: The device the item is referencing has
+ * been started and is now running.
+ * @STC_ITEM_STATE_DEFUNCT: The device the item is referencing has
+ * been started but the device the item (or
+ * one of its dependencies) is referencing
+ * has disappeared in the meantime.
*
* Enumeration describing the current state of the object described by a #StcItem.
*/
@@ -82,6 +95,7 @@ typedef enum
STC_ITEM_STATE_CAN_START_DEGRADED,
STC_ITEM_STATE_CAN_START,
STC_ITEM_STATE_STARTED,
+ STC_ITEM_STATE_DEFUNCT
} StcItemState;
G_END_DECLS
diff --git a/stc/stcitem.c b/stc/stcitem.c
index 2f664f1..8b30f1f 100644
--- a/stc/stcitem.c
+++ b/stc/stcitem.c
@@ -482,8 +482,10 @@ _stc_item_mdraid_get_devices (StcItem *item,
ret_component_devices = NULL;
ret = NULL;
+ /* see data/79-stc.rules for why STC_ORIG_MD_NAME, STC_ORIG_MD_UUID is used */
if (g_str_has_prefix (item->target, "Name="))
{
+ /* first find the components */
devices = _g_udev_client_query_by_property (_stc_monitor_get_gudev_client (item->monitor),
"block",
"MD_NAME",
@@ -502,10 +504,21 @@ _stc_item_mdraid_get_devices (StcItem *item,
md_level = g_strdup (g_udev_device_get_property (device, "MD_LEVEL"));
ret_component_devices = g_list_prepend (ret_component_devices, g_object_ref (device));
}
- else if (!g_udev_device_has_property (device, "MD_EVENTS"))
+ }
+ g_list_foreach (devices, (GFunc) g_object_unref, NULL);
+ g_list_free (devices);
+ /* then the array itself */
+ devices = _g_udev_client_query_by_property (_stc_monitor_get_gudev_client (item->monitor),
+ "block",
+ "STC_ORIG_MD_NAME",
+ item->target + sizeof "Name=" - 1);
+ for (l = devices; l != NULL; l = l->next)
+ {
+ device = G_UDEV_DEVICE (l->data);
+ if (ret == NULL)
{
- if (ret == NULL)
- ret = g_object_ref (device);
+ ret = g_object_ref (device);
+ break;
}
}
g_list_foreach (devices, (GFunc) g_object_unref, NULL);
@@ -513,6 +526,7 @@ _stc_item_mdraid_get_devices (StcItem *item,
}
else if (g_str_has_prefix (item->target, "UUID="))
{
+ /* first find the components */
devices = _g_udev_client_query_by_property (_stc_monitor_get_gudev_client (item->monitor),
"block",
"MD_UUID",
@@ -531,10 +545,21 @@ _stc_item_mdraid_get_devices (StcItem *item,
md_level = g_strdup (g_udev_device_get_property (device, "MD_LEVEL"));
ret_component_devices = g_list_prepend (ret_component_devices, g_object_ref (device));
}
- else if (!g_udev_device_has_property (device, "MD_EVENTS"))
+ }
+ g_list_foreach (devices, (GFunc) g_object_unref, NULL);
+ g_list_free (devices);
+ /* then the array itself */
+ devices = _g_udev_client_query_by_property (_stc_monitor_get_gudev_client (item->monitor),
+ "block",
+ "STC_ORIG_MD_UUID",
+ item->target + sizeof "UUID=" - 1);
+ for (l = devices; l != NULL; l = l->next)
+ {
+ device = G_UDEV_DEVICE (l->data);
+ if (ret == NULL)
{
- if (ret == NULL)
- ret = g_object_ref (device);
+ ret = g_object_ref (device);
+ break;
}
}
g_list_foreach (devices, (GFunc) g_object_unref, NULL);
@@ -570,6 +595,27 @@ _stc_item_mdraid_get_devices (StcItem *item,
/* ---------------------------------------------------------------------------------------------------- */
static gboolean
+block_dev_exists (GUdevClient *client,
+ dev_t dev)
+{
+ gboolean ret;
+ GUdevDevice *device;
+
+ ret = FALSE;
+
+ device = g_udev_client_query_by_device_number (client,
+ G_UDEV_DEVICE_TYPE_BLOCK,
+ dev);
+ if (device != NULL)
+ {
+ ret = TRUE;
+ g_object_unref (device);
+ }
+
+ return ret;
+}
+
+static gboolean
_strv_has_str (gchar **strv,
const gchar *str)
{
@@ -620,6 +666,29 @@ _stc_item_update_state_filesystem (StcItem *item)
g_object_unref (device);
}
+ else
+ {
+ const gchar *desired_mount_path;
+ _StcMount *mount;
+
+ /* could be we are defunct - this happens exactly when there is a mount
+ * at our desired mount path referencing a block device that no longer
+ * exists
+ */
+ desired_mount_path = g_hash_table_lookup (item->options, "FilesystemMountPath");
+ g_assert (desired_mount_path != NULL);
+ mount = _stc_mount_monitor_get_mount_for_path (_stc_monitor_get_mount_monitor (item->monitor),
+ desired_mount_path);
+ if (mount != NULL)
+ {
+ if (!block_dev_exists (_stc_monitor_get_gudev_client (item->monitor),
+ _stc_mount_get_dev (mount)))
+ {
+ ret = STC_ITEM_STATE_DEFUNCT;
+ }
+ g_object_unref (mount);
+ }
+ }
return ret;
}
@@ -654,26 +723,16 @@ _stc_item_luks_get_devices (StcItem *item,
GUdevDevice *device;
GList *devices;
GList *l;
+ gchar *luks_uuid;
+ gchar *uuid_prefix;
device_with_crypto = NULL;
unlocked_device = NULL;
+ luks_uuid = NULL;
- if (g_str_has_prefix (item->target, "Device="))
- {
- device = g_udev_client_query_by_device_file (_stc_monitor_get_gudev_client (item->monitor),
- item->target + sizeof "Device=" - 1);
- if (device != NULL)
- {
- if (g_strcmp0 (g_udev_device_get_property (device, "ID_FS_USAGE"), "crypto") == 0 &&
- g_strcmp0 (g_udev_device_get_property (device, "ID_FS_TYPE"), "crypto_LUKS") == 0)
- {
- device_with_crypto = g_object_ref (device);
- }
- g_object_unref (device);
- }
- }
- else if (g_str_has_prefix (item->target, "UUID="))
+ if (g_str_has_prefix (item->target, "UUID="))
{
+ luks_uuid = _strdup_without_dashes (item->target + sizeof "UUID=" - 1);
devices = _g_udev_client_query_by_property (_stc_monitor_get_gudev_client (item->monitor),
"block",
"ID_FS_UUID",
@@ -696,15 +755,11 @@ _stc_item_luks_get_devices (StcItem *item,
g_warning ("Unsupported target type %s for Luks", item->target);
}
- if (device_with_crypto != NULL)
+ /* if a LUKS device is unlocked, then DM_UUID is set to uuid_prefix plus the name - so
+ * just check the prefix to check for existance
+ */
+ if (luks_uuid != NULL)
{
- gchar *uuid_prefix;
- gchar *luks_uuid;
-
- /* if a LUKS device is unlocked, then DM_UUID is set to uuid_prefix plus the name - so
- * just check the prefix
- */
- luks_uuid = _strdup_without_dashes (g_udev_device_get_property (device_with_crypto, "ID_FS_UUID"));
uuid_prefix = g_strdup_printf ("CRYPT-LUKS1-%s", luks_uuid);
devices = g_udev_client_query_by_subsystem (_stc_monitor_get_gudev_client (item->monitor), "block");
for (l = devices; l != NULL; l = l->next)
@@ -721,6 +776,7 @@ _stc_item_luks_get_devices (StcItem *item,
g_list_foreach (devices, (GFunc) g_object_unref, NULL);
g_list_free (devices);
g_free (uuid_prefix);
+ g_free (luks_uuid);
}
if (out_unlocked_device != NULL)
@@ -759,15 +815,77 @@ _stc_item_update_state_luks (StcItem *item)
if (unlocked_device != NULL)
{
item->resulting_device = g_strdup (g_udev_device_get_device_file (unlocked_device));
- g_object_unref (unlocked_device);
ret = STC_ITEM_STATE_STARTED;
}
- g_object_unref (device_with_crypto);
}
+ else
+ {
+ /* could be we are defunct */
+ if (unlocked_device != NULL)
+ {
+ ret = STC_ITEM_STATE_DEFUNCT;
+ }
+ }
+
+ if (unlocked_device != NULL)
+ g_object_unref (unlocked_device);
+ if (device_with_crypto != NULL)
+ g_object_unref (device_with_crypto);
return ret;
}
+static void
+_stc_item_compute_can_start (const gchar *md_level,
+ guint md_devices,
+ guint num_components,
+ gboolean *out_can_run,
+ gboolean *out_can_run_degraded)
+{
+ gboolean can_run;
+ gboolean can_run_degraded;
+
+ can_run = FALSE;
+ can_run_degraded = FALSE;
+
+ if (g_strcmp0 (md_level, "raid0") == 0)
+ {
+ if (num_components == md_devices)
+ can_run = TRUE;
+ }
+ else if (g_strcmp0 (md_level, "raid1") == 0)
+ {
+ if (num_components >= 1)
+ can_run_degraded = TRUE;
+ if (num_components == md_devices)
+ can_run = TRUE;
+ }
+ else if (g_strcmp0 (md_level, "raid5") == 0)
+ {
+ if (md_devices - num_components <= 1)
+ can_run_degraded = TRUE;
+ if (num_components == md_devices)
+ can_run = TRUE;
+ }
+ else if (g_strcmp0 (md_level, "raid6") == 0)
+ {
+ if (md_devices - num_components <= 2)
+ can_run_degraded = TRUE;
+ if (num_components == md_devices)
+ can_run = TRUE;
+ }
+ else if (md_level != NULL)
+ {
+ g_warning ("Unhandled md_level string `%s'", md_level);
+ can_run = TRUE;
+ }
+
+ if (out_can_run_degraded != NULL)
+ *out_can_run_degraded = can_run_degraded;
+ if (out_can_run != NULL)
+ *out_can_run = can_run;
+}
+
static StcItemState
_stc_item_update_state_raid (StcItem *item)
{
@@ -777,6 +895,8 @@ _stc_item_update_state_raid (StcItem *item)
gint num_components;
gint num_devices;
gchar *md_level;
+ gboolean can_run;
+ gboolean can_run_degraded;
ret = STC_ITEM_STATE_NOT_STARTED;
@@ -817,41 +937,52 @@ _stc_item_update_state_raid (StcItem *item)
item->slave_devices = (gchar **) g_ptr_array_free (p, FALSE);
}
- if (g_strcmp0 (md_level, "raid0") == 0)
- {
- if (num_components == num_devices)
- ret = STC_ITEM_STATE_CAN_START;
- }
- else if (g_strcmp0 (md_level, "raid1") == 0)
- {
- if (num_components >= 1)
- ret = STC_ITEM_STATE_CAN_START_DEGRADED;
- if (num_components == num_devices)
- ret = STC_ITEM_STATE_CAN_START;
- }
- else if (g_strcmp0 (md_level, "raid5") == 0)
- {
- if (num_devices - num_components <= 1)
- ret = STC_ITEM_STATE_CAN_START_DEGRADED;
- if (num_components == num_devices)
- ret = STC_ITEM_STATE_CAN_START;
- }
- else if (g_strcmp0 (md_level, "raid6") == 0)
- {
- if (num_devices - num_components <= 2)
- ret = STC_ITEM_STATE_CAN_START_DEGRADED;
- if (num_components == num_devices)
- ret = STC_ITEM_STATE_CAN_START;
- }
- else if (md_level != NULL)
- {
- g_warning ("Unhandled md_level string `%s'", md_level);
- }
+ _stc_item_compute_can_start (md_level,
+ num_devices,
+ num_components,
+ &can_run,
+ &can_run_degraded);
+ if (can_run)
+ ret = STC_ITEM_STATE_CAN_START;
+ else if (can_run_degraded)
+ ret = STC_ITEM_STATE_CAN_START_DEGRADED;
if (array_device != NULL)
{
+ gint n;
+ gint num_working_components;
+
ret = STC_ITEM_STATE_STARTED;
item->resulting_device = g_strdup (g_udev_device_get_device_file (array_device));
+
+ /* the array could be defunct - to check this we look count
+ * number of valid rdNN/block symlinks in sysfs - this is
+ * equal the number of working components
+ */
+ num_working_components = 0;
+ for (n = 0; n < num_devices; n++)
+ {
+ gchar *path;
+ gchar *link;
+ path = g_strdup_printf ("%s/md/rd%d",
+ g_udev_device_get_sysfs_path (array_device),
+ n);
+ link = g_file_read_link (path, NULL);
+ if (link != NULL)
+ {
+ num_working_components++;
+ g_free (link);
+ }
+ g_free (path);
+ }
+
+ _stc_item_compute_can_start (md_level,
+ num_devices,
+ num_working_components,
+ &can_run,
+ &can_run_degraded);
+ if (!(can_run || can_run_degraded))
+ ret = STC_ITEM_STATE_DEFUNCT;
}
g_list_foreach (component_devices, (GFunc) g_object_unref, NULL);
@@ -867,76 +998,145 @@ gboolean
_stc_item_update_state (StcItem *item)
{
StcItemState state;
+ StcItemState own_state;
guint n;
gboolean changed;
+ guint num_deps;
+ guint num_broken_deps;
+ guint num_not_started_deps;
+ guint num_can_start_deps;
+ guint num_can_start_degraded_deps;
+ guint num_started_deps;
+ guint num_defunct_deps;
g_return_val_if_fail (STC_IS_ITEM (item), FALSE);
- state = STC_ITEM_STATE_STARTED;
+ num_deps = 0;
+ num_broken_deps = 0;
+ num_not_started_deps = 0;
+ num_can_start_deps = 0;
+ num_can_start_degraded_deps = 0;
+ num_started_deps = 0;
+ num_defunct_deps = 0;
/* first check all deps */
for (n = 0; item->depends != NULL && item->depends[n] != NULL; n++)
{
StcItem *depend_item;
- StcItemState depend_item_state;
+ num_deps++;
depend_item = stc_monitor_get_item_by_id (item->monitor, item->depends[n]);
if (depend_item == NULL)
{
/* broken dep - means this item is NOT_STARTED */
state = STC_ITEM_STATE_NOT_STARTED;
- goto dep_check_out;
+ num_broken_deps++;
}
+ else
+ {
+ switch (stc_item_get_state (depend_item))
+ {
+ case STC_ITEM_STATE_NOT_STARTED:
+ num_not_started_deps++;
+ break;
- depend_item_state = stc_item_get_state (depend_item);
- g_object_unref (depend_item);
+ case STC_ITEM_STATE_CAN_START:
+ num_can_start_deps++;
+ break;
- switch (depend_item_state)
- {
- case STC_ITEM_STATE_NOT_STARTED:
- /* means we are NOT_STARTED too */
- state = STC_ITEM_STATE_NOT_STARTED;
- goto dep_check_out;
+ case STC_ITEM_STATE_CAN_START_DEGRADED:
+ num_can_start_degraded_deps++;
+ break;
- case STC_ITEM_STATE_STARTED:
- /* all good */
- break;
+ case STC_ITEM_STATE_STARTED:
+ num_started_deps++;
+ break;
- case STC_ITEM_STATE_CAN_START:
- case STC_ITEM_STATE_CAN_START_DEGRADED:
- /* if we are already CAN_START_DEGRADED, stay there... otherwise
- * we want to be DEGRADED if the dependent is DEGRADED...
- */
- if (state == STC_ITEM_STATE_CAN_START_DEGRADED)
- ;
- else
- state = depend_item_state;
- break;
+ case STC_ITEM_STATE_DEFUNCT:
+ num_defunct_deps++;
+ break;
+ }
+ g_object_unref (depend_item);
}
}
- dep_check_out:
- /* we only need to examine our own state if all dependencies are fulfilled */
- if (state == STC_ITEM_STATE_STARTED)
+ /* now calculate our own state */
+ switch (item->type)
{
- switch (item->type)
- {
- case STC_ITEM_TYPE_FILESYSTEM:
- state = _stc_item_update_state_filesystem (item);
- break;
+ case STC_ITEM_TYPE_FILESYSTEM:
+ own_state = _stc_item_update_state_filesystem (item);
+ break;
- case STC_ITEM_TYPE_LUKS:
- state = _stc_item_update_state_luks (item);
- break;
+ case STC_ITEM_TYPE_LUKS:
+ own_state = _stc_item_update_state_luks (item);
+ break;
- case STC_ITEM_TYPE_RAID:
- state = _stc_item_update_state_raid (item);
- break;
+ case STC_ITEM_TYPE_RAID:
+ own_state = _stc_item_update_state_raid (item);
+ break;
- default:
- g_assert_not_reached ();
- break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+#if 0
+ g_printerr ("item %s\n"
+ " own_state = %d\n"
+ " num = %d\n"
+ " num_broken = %d\n"
+ " num_not_started = %d\n"
+ " num_can_start = %d\n"
+ " num_can_start_degraded = %d\n"
+ " num_started = %d\n"
+ " num_defunct = %d\n",
+ item->id,
+ own_state,
+ num_deps,
+ num_broken_deps,
+ num_not_started_deps,
+ num_can_start_deps,
+ num_can_start_degraded_deps,
+ num_started_deps,
+ num_defunct_deps);
+#endif
+
+ /* and use this to calculate the combined state */
+ switch (own_state)
+ {
+ case STC_ITEM_STATE_NOT_STARTED:
+ state = STC_ITEM_STATE_NOT_STARTED;
+ if (num_deps > 0)
+ {
+ if (num_can_start_deps + num_started_deps == num_deps)
+ state = STC_ITEM_STATE_CAN_START;
+ else if (num_can_start_degraded_deps + num_can_start_deps + num_started_deps == num_deps)
+ state = STC_ITEM_STATE_CAN_START_DEGRADED;
}
+ break;
+
+ case STC_ITEM_STATE_CAN_START:
+ if (num_can_start_deps + num_started_deps == num_deps)
+ state = STC_ITEM_STATE_CAN_START;
+ else if (num_can_start_degraded_deps + num_can_start_deps + num_started_deps == num_deps)
+ state = STC_ITEM_STATE_CAN_START_DEGRADED;
+ break;
+
+ case STC_ITEM_STATE_CAN_START_DEGRADED:
+ if (num_can_start_degraded_deps + num_can_start_deps + num_started_deps == num_deps)
+ state = STC_ITEM_STATE_CAN_START_DEGRADED;
+ break;
+
+ case STC_ITEM_STATE_STARTED:
+ if (num_started_deps == num_deps)
+ state = STC_ITEM_STATE_STARTED;
+ else
+ state = STC_ITEM_STATE_DEFUNCT;
+ break;
+
+ case STC_ITEM_STATE_DEFUNCT:
+ state = STC_ITEM_STATE_DEFUNCT;
+ break;
}
changed = FALSE;
@@ -2058,61 +2258,30 @@ _stc_item_stop_filesystem (StcItem *item,
GError **error)
{
gboolean ret;
- GUdevDevice *device;
- gchar **mount_paths;
-
- ret = FALSE;
+ const gchar *opt_mount_path;
+ gchar *q_mount_path;
+ gchar *command_line;
- device = _stc_item_filesystem_get_device (item, &mount_paths);
- if (device != NULL)
- {
- const gchar *opt_mount_path;
+ /* TODO: use lazy unmount if unmounting defunct item */
- opt_mount_path = g_hash_table_lookup (item->options, "FilesystemMountPath");
- g_assert (opt_mount_path != NULL);
+ ret = FALSE;
- if (_strv_has_str (mount_paths, opt_mount_path))
- {
- gchar *q_mount_path;
- gchar *command_line;
+ opt_mount_path = g_hash_table_lookup (item->options, "FilesystemMountPath");
+ g_assert (opt_mount_path != NULL);
- q_mount_path = g_shell_quote (opt_mount_path);
- command_line = g_strdup_printf ("umount %s", q_mount_path);
- g_free (q_mount_path);
+ q_mount_path = g_shell_quote (opt_mount_path);
+ command_line = g_strdup_printf ("umount %s", q_mount_path);
+ g_free (q_mount_path);
- if (!run_command_line_sync_simple (command_line,
- NULL,
- cancellable,
- error))
- {
- g_free (command_line);
- goto out;
- }
- g_free (command_line);
- }
- else
- {
- g_set_error (error,
- STC_ERROR,
- STC_ERROR_FAILED,
- "Device is not mounted at %s",
- opt_mount_path);
- g_object_unref (device);
- g_strfreev (mount_paths);
- goto out;
- }
- g_object_unref (device);
- g_strfreev (mount_paths);
- }
- else
+ if (!run_command_line_sync_simple (command_line,
+ NULL,
+ cancellable,
+ error))
{
- g_set_error (error,
- STC_ERROR,
- STC_ERROR_FAILED,
- "Did not find a device file corresponding to Filesystem item %s",
- item->id);
+ g_free (command_line);
goto out;
}
+ g_free (command_line);
ret = TRUE;
@@ -2141,15 +2310,6 @@ _stc_item_stop_luks (StcItem *item,
device_with_crypto = _stc_item_luks_get_devices (item, &unlocked_device);
- if (device_with_crypto == NULL)
- {
- g_set_error (error,
- STC_ERROR,
- STC_ERROR_FAILED,
- "Cannot find device for item");
- goto out;
- }
-
if (unlocked_device == NULL)
{
g_set_error (error,
@@ -2255,6 +2415,16 @@ stc_item_stop_sync (StcItem *item,
ret = FALSE;
+ if (!(item->state == STC_ITEM_STATE_STARTED || item->state == STC_ITEM_STATE_DEFUNCT))
+ {
+ g_set_error (error,
+ STC_ERROR,
+ STC_ERROR_FAILED,
+ "Expected item to be running or defunct but state is %d",
+ item->state);
+ goto out;
+ }
+
/* first stop the item */
switch (item->type)
{
@@ -2275,12 +2445,15 @@ stc_item_stop_sync (StcItem *item,
break;
}
- if (_stc_item_update_state (item))
+ if (ret)
{
- g_signal_emit_by_name (item->monitor, "item-changed", 0, item);
- g_signal_emit (item, signals[CHANGED_SIGNAL], 0);
+ if (_stc_item_update_state (item))
+ {
+ g_signal_emit_by_name (item->monitor, "item-changed", 0, item);
+ g_signal_emit (item, signals[CHANGED_SIGNAL], 0);
+ }
+ stc_operation_stopped (operation, item);
}
- stc_operation_stopped (operation, item);
if (!ret)
goto out;
@@ -2289,7 +2462,6 @@ stc_item_stop_sync (StcItem *item,
for (n = 0; item->depends != NULL && item->depends[n] != NULL; n++)
{
StcItem *depend_item;
- StcItemState depend_item_state;
depend_item = stc_monitor_get_item_by_id (item->monitor, item->depends[n]);
if (depend_item == NULL)
@@ -2304,34 +2476,17 @@ stc_item_stop_sync (StcItem *item,
goto out;
}
- depend_item_state = stc_item_get_state (depend_item);
- switch (depend_item_state)
+ if (!stc_item_stop_sync (depend_item,
+ operation,
+ cancellable,
+ error))
{
- case STC_ITEM_STATE_STARTED:
- if (!stc_item_stop_sync (depend_item,
- operation,
- cancellable,
- error))
- {
- g_prefix_error (error, "Error stopping dependency with id %s: ",
- stc_item_get_id (depend_item));
- g_object_unref (depend_item);
- ret = FALSE;
- goto out;
- }
- break;
-
- default:
- g_set_error (error,
- STC_ERROR,
- STC_ERROR_FAILED,
- "Error stopping dependency with id %s: expected item to be running but state is %d",
- stc_item_get_id (depend_item),
- depend_item_state);
+ g_prefix_error (error, "Error stopping dependency with id %s: ",
+ stc_item_get_id (depend_item));
+ g_object_unref (depend_item);
ret = FALSE;
goto out;
}
-
g_object_unref (depend_item);
}
diff --git a/stc/stcmonitor.c b/stc/stcmonitor.c
index 7e15eee..4aeccda 100644
--- a/stc/stcmonitor.c
+++ b/stc/stcmonitor.c
@@ -635,14 +635,13 @@ check_validity (StcMonitor *monitor,
break;
case STC_ITEM_TYPE_LUKS:
- if (!(g_str_has_prefix (target, "Device=") ||
- g_str_has_prefix (target, "UUID=")))
+ if (!(g_str_has_prefix (target, "UUID=")))
{
stc_monitor_emit_stc_error (monitor,
path,
line_no,
STC_ERROR_FAILED,
- "Raid item %s has unsupported target type (UUID and Device is supported).",
+ "Raid item %s has unsupported target type (UUID is supported).",
item_id);
goto out;
}
diff --git a/stc/stcmount.h b/stc/stcmount.h
index ce8a0c3..564415d 100644
--- a/stc/stcmount.h
+++ b/stc/stcmount.h
@@ -21,7 +21,7 @@
*/
#if !defined (STC_COMPILATION)
-#error "stcmountmonitor.h is a private header file."
+#error "stcmount.h is a private header file."
#endif
#ifndef ___STC_MOUNT_H__
diff --git a/stc/stcmountmonitor.c b/stc/stcmountmonitor.c
index 615962b..75a9051 100644
--- a/stc/stcmountmonitor.c
+++ b/stc/stcmountmonitor.c
@@ -500,3 +500,41 @@ _stc_mount_monitor_get_mounts_for_dev (_StcMountMonitor *monitor,
return ret;
}
+
+/**
+ * _stc_mount_monitor_get_mount_for_path:
+ * @monitor: A #_StcMountMonitor.
+ * @mount_path: A mount path.
+ *
+ * Gets the #_StcMount for @mount_path, if any.
+ *
+ * Returns: A #_StcMount or %NULL if nothing is mounted at
+ * @mount_path. The returned object must be freed with
+ * g_object_unref().
+ */
+_StcMount *
+_stc_mount_monitor_get_mount_for_path (_StcMountMonitor *monitor,
+ const gchar *mount_path)
+{
+ GList *l;
+ _StcMount *ret;
+
+ ret = NULL;
+
+ _stc_mount_monitor_ensure (monitor);
+
+ for (l = monitor->mounts; l != NULL; l = l->next)
+ {
+ _StcMount *mount = _STC_MOUNT (l->data);
+
+ if (g_strcmp0 (_stc_mount_get_mount_path (mount), mount_path) == 0)
+ {
+ ret = g_object_ref (mount);
+ goto out;
+ }
+ }
+
+ out:
+ return ret;
+}
+
diff --git a/stc/stcmountmonitor.h b/stc/stcmountmonitor.h
index a2bb02d..a5b0f65 100644
--- a/stc/stcmountmonitor.h
+++ b/stc/stcmountmonitor.h
@@ -40,6 +40,8 @@ GType _stc_mount_monitor_get_type (void) G_GNUC_CONST;
_StcMountMonitor *_stc_mount_monitor_new (void);
GList *_stc_mount_monitor_get_mounts_for_dev (_StcMountMonitor *monitor,
dev_t dev);
+_StcMount *_stc_mount_monitor_get_mount_for_path (_StcMountMonitor *monitor,
+ const gchar *mount_path);
void _stc_mount_monitor_invalidate (_StcMountMonitor *monitor);
G_END_DECLS