static BDFSExtInfo* ext_get_info (const gchar *device, GError **error) { const gchar *args[4] = {"dumpe2fs", "-h", device, NULL}; gboolean success = FALSE; gchar *output = NULL; GHashTable *table = NULL; guint num_items = 0; BDFSExtInfo *ret = NULL; if (!check_deps (&avail_deps, DEPS_DUMPE2FS_MASK, deps, DEPS_LAST, &deps_check_lock, error)) return FALSE; success = bd_utils_exec_and_capture_output (args, NULL, &output, error); if (!success) { /* error is already populated */ return FALSE; } table = parse_output_vars (output, "\n", ":", &num_items); g_free (output); if (!table || (num_items == 0)) { /* something bad happened or some expected items were missing */ g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_PARSE, "Failed to parse ext4 file system information"); if (table) g_hash_table_destroy (table); return NULL; } ret = get_ext_info_from_table (table, TRUE); if (!ret) { g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_PARSE, "Failed to parse ext4 file system information"); return NULL; } return ret; }
/** * bd_mpath_flush_mpaths: * @error: (out): place to store error (if any) * * Returns: whether multipath device maps were successfully flushed or not * * Flushes all unused multipath device maps. */ gboolean bd_mpath_flush_mpaths (GError **error) { const gchar *argv[3] = {"multipath", "-F", NULL}; gboolean success = FALSE; gchar *output = NULL; /* try to flush the device maps */ success = bd_utils_exec_and_report_error (argv, NULL, error); if (!success) return FALSE; /* list devices (there should be none) */ argv[1] = "-ll"; success = bd_utils_exec_and_capture_output (argv, NULL, &output, error); if (success && output && (g_strcmp0 (output, "") != 0)) { g_set_error (error, BD_MPATH_ERROR, BD_MPATH_ERROR_FLUSH, "Some device cannot be flushed: %s", output); g_free (output); return FALSE; } g_free (output); return TRUE; }
/** * bd_fs_xfs_get_info: * @device: the device containing the file system to get info for (device must be mounted, trying to get info for an unmounted device will result in an error) * @error: (out): place to store error (if any) * * Returns: (transfer full): information about the file system on @device or * %NULL in case of error * * Tech category: %BD_FS_TECH_XFS-%BD_FS_TECH_MODE_QUERY */ BDFSXfsInfo* bd_fs_xfs_get_info (const gchar *device, GError **error) { const gchar *args[4] = {"xfs_admin", "-lu", device, NULL}; gboolean success = FALSE; gchar *output = NULL; BDFSXfsInfo *ret = NULL; gchar **lines = NULL; gchar **line_p = NULL; gboolean have_label = FALSE; gboolean have_uuid = FALSE; gchar *val_start = NULL; gchar *val_end = NULL; g_autofree gchar* mountpoint = NULL; if (!check_deps (&avail_deps, DEPS_XFS_ADMIN_MASK, deps, DEPS_LAST, &deps_check_lock, error)) return FALSE; mountpoint = bd_fs_get_mountpoint (device, error); if (mountpoint == NULL) { if (*error == NULL) { g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_NOT_MOUNTED, "Can't get xfs file system information for '%s': Device is not mounted.", device); return NULL; } else { g_prefix_error (error, "Error when trying to get mountpoint for '%s': ", device); return NULL; } } success = bd_utils_exec_and_capture_output (args, NULL, &output, error); if (!success) /* error is already populated */ return FALSE; ret = g_new0 (BDFSXfsInfo, 1); lines = g_strsplit (output, "\n", 0); g_free (output); for (line_p=lines; line_p && *line_p && (!have_label || !have_uuid); line_p++) { if (!have_label && g_str_has_prefix (*line_p, "label")) { /* extract label from something like this: label = "TEST_LABEL" */ val_start = strchr (*line_p, '"'); if (val_start) val_end = strchr(val_start + 1, '"'); if (val_start && val_end) { ret->label = g_strndup (val_start + 1, val_end - val_start - 1); have_label = TRUE; } } else if (!have_uuid && g_str_has_prefix (*line_p, "UUID")) { /* get right after the "UUID = " prefix */ val_start = *line_p + 7; ret->uuid = g_strdup (val_start); have_uuid = TRUE; } } g_strfreev (lines); args[0] = "xfs_info"; args[1] = mountpoint; args[2] = NULL; success = bd_utils_exec_and_capture_output (args, NULL, &output, error); if (!success) { /* error is already populated */ bd_fs_xfs_info_free (ret); return FALSE; } lines = g_strsplit (output, "\n", 0); g_free (output); line_p = lines; /* find the beginning of the (data) section we are interested in */ while (line_p && *line_p && !g_str_has_prefix (*line_p, "data")) line_p++; if (!line_p || !(*line_p)) { /* error is already populated */ g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_PARSE, "Failed to parse xfs file system information"); g_strfreev (lines); bd_fs_xfs_info_free (ret); return FALSE; } /* extract data from something like this: "data = bsize=4096 blocks=262400, imaxpct=25" */ val_start = strchr (*line_p, '='); val_start++; while (isspace (*val_start)) val_start++; if (g_str_has_prefix (val_start, "bsize")) { val_start = strchr (val_start, '='); val_start++; ret->block_size = g_ascii_strtoull (val_start, NULL, 0); } else { /* error is already populated */ g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_PARSE, "Failed to parse xfs file system information"); g_strfreev (lines); bd_fs_xfs_info_free (ret); return FALSE; } while (isdigit (*val_start) || isspace(*val_start)) val_start++; if (g_str_has_prefix (val_start, "blocks")) { val_start = strchr (val_start, '='); val_start++; ret->block_count = g_ascii_strtoull (val_start, NULL, 0); } else { /* error is already populated */ g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_PARSE, "Failed to parse xfs file system information"); g_strfreev (lines); bd_fs_xfs_info_free (ret); return FALSE; } g_strfreev (lines); return ret; }
/** * bd_fs_ntfs_get_info: * @device: the device containing the file system to get info for (device must not be mounted, trying to get info for a mounted device will result in an error) * @error: (out): place to store error (if any) * * Returns: (transfer full): information about the file system on @device or * %NULL in case of error * * Tech category: %BD_FS_TECH_NTFS-%BD_FS_TECH_MODE_QUERY */ BDFSNtfsInfo* bd_fs_ntfs_get_info (const gchar *device, GError **error) { const gchar *args[3] = {"ntfscluster", device, NULL}; gboolean success = FALSE; gchar *output = NULL; BDFSNtfsInfo *ret = NULL; gchar **lines = NULL; gchar **line_p = NULL; gchar *val_start = NULL; g_autofree gchar* mountpoint = NULL; if (!check_deps (&avail_deps, DEPS_NTFSCLUSTER_MASK, deps, DEPS_LAST, &deps_check_lock, error)) return FALSE; mountpoint = bd_fs_get_mountpoint (device, error); if (mountpoint != NULL) { g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_NOT_MOUNTED, "Can't get NTFS file system information for '%s': Device is mounted.", device); return NULL; } else { if (*error != NULL) { g_prefix_error (error, "Error when trying to get mountpoint for '%s': ", device); return NULL; } } success = bd_utils_exec_and_capture_output (args, NULL, &output, error); if (!success) /* error is already populated */ return FALSE; ret = g_new0 (BDFSNtfsInfo, 1); lines = g_strsplit (output, "\n", 0); g_free (output); line_p = lines; /* find the beginning of the (data) section we are interested in */ while (line_p && *line_p && !g_str_has_prefix (*line_p, "bytes per volume")) line_p++; if (!line_p || !(*line_p)) { g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_PARSE, "Failed to parse NTFS file system information"); g_strfreev (lines); bd_fs_ntfs_info_free (ret); return FALSE; } /* extract data from something like this: "bytes per volume : 998240256" */ val_start = strchr (*line_p, ':'); val_start++; ret->size = g_ascii_strtoull (val_start, NULL, 0); while (line_p && *line_p && !g_str_has_prefix (*line_p, "bytes of free space")) line_p++; if (!line_p || !(*line_p)) { g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_PARSE, "Failed to parse NTFS file system information"); g_strfreev (lines); bd_fs_ntfs_info_free (ret); return FALSE; } /* extract data from something like this: "bytes of free space : 992759808" */ val_start = strchr (*line_p, ':'); val_start++; ret->free_space = g_ascii_strtoull (val_start, NULL, 0); g_strfreev (lines); return ret; }