diff options
author | David Zeuthen <davidz@redhat.com> | 2010-10-08 10:11:34 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2010-10-08 10:11:34 -0400 |
commit | d1a9155cf6dd7818b64d586c727555eab4a62ec8 (patch) | |
tree | 77af4a62704dc869be81103729ce7ba3c2279d75 | |
parent | 68f743407bc7ba627add70b0cd3b103a8f813690 (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.rules | 18 | ||||
-rw-r--r-- | data/Makefile.am | 6 | ||||
-rw-r--r-- | doc/stc.conf.xml | 9 | ||||
-rw-r--r-- | doc/stc.xml | 4 | ||||
-rw-r--r-- | stc/stc.c | 3 | ||||
-rw-r--r-- | stc/stcenums.h | 22 | ||||
-rw-r--r-- | stc/stcitem.c | 529 | ||||
-rw-r--r-- | stc/stcmonitor.c | 5 | ||||
-rw-r--r-- | stc/stcmount.h | 2 | ||||
-rw-r--r-- | stc/stcmountmonitor.c | 38 | ||||
-rw-r--r-- | stc/stcmountmonitor.h | 2 |
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> @@ -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 |