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
Copy link
Copy Markdown

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;
}
Comment on lines +793 to +802
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This error handling logic is very similar in the three blocks you've added (here, and at lines 822-832, 853-864) and also resembles other error paths in this function. This leads to a lot of duplicated code, which is difficult to maintain. Since this function deals with many allocated resources inside a loop, consider refactoring to centralize cleanup. A common C idiom is to use goto to a cleanup label.

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