Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/plugins/fs/xfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,11 +398,23 @@ BDFSXfsInfo* bd_fs_xfs_get_info (const gchar *device, GError **error) {

/* extract data from something like this: "data = bsize=4096 blocks=262400, imaxpct=25" */
val_start = strchr (*line_p, '=');
if (!val_start) {
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 NULL;
}
Comment on lines +401 to +406

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While adding this null check is crucial for correctness, the error handling logic is now duplicated in multiple places within this function (e.g., lines 401-406, 412-417, 430-435, and also in existing code). This makes the code harder to maintain and prone to errors if a cleanup path is modified in one place but not others.

Consider refactoring to use a single cleanup point with goto. This is a common and idiomatic pattern in C for handling resource cleanup and would centralize the logic, reduce duplication, and improve readability.

val_start++;
while (isspace (*val_start))
val_start++;
if (g_str_has_prefix (val_start, "bsize")) {
val_start = strchr (val_start, '=');
if (!val_start) {
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 NULL;
}
val_start++;
ret->block_size = g_ascii_strtoull (val_start, NULL, 0);
} else {
Expand All @@ -415,6 +427,12 @@ BDFSXfsInfo* bd_fs_xfs_get_info (const gchar *device, GError **error) {
val_start++;
if (g_str_has_prefix (val_start, "blocks")) {
val_start = strchr (val_start, '=');
if (!val_start) {
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 NULL;
}
val_start++;
ret->block_count = g_ascii_strtoull (val_start, NULL, 0);
} else {
Expand Down
35 changes: 34 additions & 1 deletion src/plugins/s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -790,10 +790,20 @@ gboolean bd_s390_zfcp_scsi_offline (const gchar *devno, const gchar *wwpn, const
hba_path = g_strdup_printf ("%s/hba_id", fcpsysfs);
len = 0; /* should be zero, but re-set it just in case */
fd = fopen (hba_path, "r");
if (!fd) {
g_set_error (&l_error, BD_S390_ERROR, BD_S390_ERROR_DEVICE,
"Failed to open %s: %m", hba_path);
g_free (hba_path);
g_free (fcpsysfs);
g_free (scsidev);
bd_utils_report_finished (progress_id, l_error->message);
g_propagate_error (error, l_error);
return FALSE;
}
rc = getline (&fcphbasysfs, &len, fd);
if (rc == -1) {
g_set_error (&l_error, BD_S390_ERROR, BD_S390_ERROR_DEVICE,
"Failed to read value from %s", hba_path);
"Failed to read value from %s: %m", hba_path);
fclose (fd);
g_free (hba_path);
g_free (fcpsysfs);
Expand All @@ -809,6 +819,17 @@ gboolean bd_s390_zfcp_scsi_offline (const gchar *devno, const gchar *wwpn, const
wwpn_path = g_strdup_printf ("%s/wwpn", fcpsysfs);
len = 0;
fd = fopen (wwpn_path, "r");
if (!fd) {
g_set_error (&l_error, BD_S390_ERROR, BD_S390_ERROR_DEVICE,
"Failed to open %s: %m", wwpn_path);
g_free (wwpn_path);
g_free (fcphbasysfs);
g_free (fcpsysfs);
g_free (scsidev);
bd_utils_report_finished (progress_id, l_error->message);
g_propagate_error (error, l_error);
return FALSE;
}
rc = getline (&fcpwwpnsysfs, &len, fd);
if (rc == -1) {
g_set_error (&l_error, BD_S390_ERROR, BD_S390_ERROR_DEVICE,
Expand All @@ -829,6 +850,18 @@ gboolean bd_s390_zfcp_scsi_offline (const gchar *devno, const gchar *wwpn, const
lun_path = g_strdup_printf ("%s/fcp_lun", fcpsysfs);
len = 0;
fd = fopen (lun_path, "r");
if (!fd) {
g_set_error (&l_error, BD_S390_ERROR, BD_S390_ERROR_DEVICE,
"Failed to open %s: %m", lun_path);
g_free (lun_path);
g_free (fcpwwpnsysfs);
g_free (fcphbasysfs);
g_free (fcpsysfs);
g_free (scsidev);
bd_utils_report_finished (progress_id, l_error->message);
g_propagate_error (error, l_error);
return FALSE;
}
rc = getline (&fcplunsysfs, &len, fd);
if (rc == -1) {
g_set_error (&l_error, BD_S390_ERROR, BD_S390_ERROR_DEVICE,
Expand Down
49 changes: 30 additions & 19 deletions src/utils/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,36 +274,34 @@ static gboolean have_linux_ver = FALSE;

G_LOCK_DEFINE_STATIC (detected_linux_ver);

/**
* bd_utils_get_linux_version:
* @error: (out) (optional): place to store error (if any)
*
* Retrieves version of currently running Linux kernel. Acts also as an initializer for statically cached data.
*
* Returns: (transfer none): Detected Linux kernel version or %NULL in case of an error. The returned value belongs to the library, do not free.
*/
BDUtilsLinuxVersion * bd_utils_get_linux_version (GError **error) {
BDUtilsLinuxVersion * _get_linux_version (gboolean lock, GError **error) {
struct utsname buf;

if (lock)
G_LOCK (detected_linux_ver);

/* return cached value if available */
if (have_linux_ver)
if (have_linux_ver) {
if (lock)
G_UNLOCK (detected_linux_ver);
return &detected_linux_ver;

G_LOCK (detected_linux_ver);
}

memset (&detected_linux_ver, 0, sizeof (BDUtilsLinuxVersion));

if (uname (&buf)) {
g_set_error (error, BD_UTILS_MODULE_ERROR, BD_UTILS_MODULE_ERROR_FAIL,
"Failed to get linux kernel version: %m");
G_UNLOCK (detected_linux_ver);
if (lock)
G_UNLOCK (detected_linux_ver);
return NULL;
}

if (g_ascii_strncasecmp (buf.sysname, "Linux", sizeof buf.sysname) != 0) {
g_set_error (error, BD_UTILS_MODULE_ERROR, BD_UTILS_MODULE_ERROR_INVALID_PLATFORM,
"Failed to get kernel version: spurious sysname '%s' detected", buf.sysname);
G_UNLOCK (detected_linux_ver);
if (lock)
G_UNLOCK (detected_linux_ver);
return NULL;
}

Expand All @@ -313,16 +311,29 @@ BDUtilsLinuxVersion * bd_utils_get_linux_version (GError **error) {
&detected_linux_ver.micro) < 1) {
g_set_error (error, BD_UTILS_MODULE_ERROR, BD_UTILS_MODULE_ERROR_FAIL,
"Failed to parse kernel version: malformed release string '%s'", buf.release);
G_UNLOCK (detected_linux_ver);
if (lock)
G_UNLOCK (detected_linux_ver);
return NULL;
}

have_linux_ver = TRUE;
G_UNLOCK (detected_linux_ver);

if (lock)
G_UNLOCK (detected_linux_ver);
return &detected_linux_ver;
}

/**
* bd_utils_get_linux_version:
* @error: (out) (optional): place to store error (if any)
*
* Retrieves version of currently running Linux kernel. Acts also as an initializer for statically cached data.
*
* Returns: (transfer none): Detected Linux kernel version or %NULL in case of an error. The returned value belongs to the library, do not free.
*/
BDUtilsLinuxVersion * bd_utils_get_linux_version (GError **error) {
return _get_linux_version (TRUE, error);
}

/**
* bd_utils_check_linux_version:
* @major: Minimal major linux kernel version.
Expand All @@ -337,10 +348,10 @@ BDUtilsLinuxVersion * bd_utils_get_linux_version (GError **error) {
gint bd_utils_check_linux_version (guint major, guint minor, guint micro) {
gint ret;

G_LOCK (detected_linux_ver);
if (!have_linux_ver)
bd_utils_get_linux_version (NULL);
_get_linux_version (FALSE, NULL);

G_LOCK (detected_linux_ver);
ret = detected_linux_ver.major - major;
if (ret == 0)
ret = detected_linux_ver.minor - minor;
Expand Down