Example #1
0
/*
 *  fwts_summary_init()
 *	free up summary lists
 */
void fwts_summary_deinit(void)
{
	int i;

	for (i = 0; i < SUMMARY_MAX; i++)
		if (fwts_summaries[i])
			fwts_list_free(fwts_summaries[i], fwts_summary_item_free);
}
Example #2
0
File: s4.c Project: 9elements/fwts
static int s4_init(fwts_framework *fw)
{
	fwts_list* swap_devs;

	swap_devs = fwts_file_open_and_read("/proc/swaps");
	if (fwts_text_list_strstr(swap_devs, "/dev/") == NULL) {
		fwts_list_free(swap_devs, free);
		fwts_failed(fw, LOG_LEVEL_MEDIUM, "NoSwap",
			"Cannot run hibernate test - machine appears to have NO swap.");
		return FWTS_ERROR;
	}
	fwts_list_free(swap_devs, free);

	if (fwts_wakealarm_test_firing(fw, 1)) {
		fwts_log_error(fw, "Cannot automatically wake machine up - aborting S4 test.");
		fwts_failed(fw, LOG_LEVEL_MEDIUM, "BadWakeAlarmS4",
			"Check if wakealarm works reliably for S4 tests.");
		return FWTS_ERROR;
	}

	return FWTS_OK;
}
Example #3
0
/*
 *  fwts_acpi_deinit()
 *	Close ACPIA engine and free method namespace
 */
int fwts_acpi_deinit(fwts_framework *fw)
{
	int ret = FWTS_ERROR;

	FWTS_UNUSED(fw);

	if (fwts_acpi_initialized) {
		fwts_list_free(fwts_object_names, free);
		fwts_object_names = NULL;
		ret = fwts_acpica_deinit();

		fwts_acpi_initialized = false;
	}

	return ret;
}
Example #4
0
File: s4.c Project: 9elements/fwts
static int s4_hibernate(fwts_framework *fw,
	int *klog_errors,
	int *hw_errors,
	int *pm_errors,
	int *klog_oopses,
	int *klog_warn_ons,
	int *failed_alloc_image,
	int percent)
{
	fwts_list *klog_pre, *klog_post, *klog_diff;
	fwts_hwinfo hwinfo1, hwinfo2;
	int status;
	int duration;
	int differences;
	int rc = FWTS_OK;
	char *command = NULL;
	char *quirks = NULL;
	fwts_pm_method_vars *fwts_settings;

	int (*do_s4)(fwts_pm_method_vars *, const int, int*, const char*);

	fwts_settings = calloc(1, sizeof(fwts_pm_method_vars));
	if (fwts_settings == NULL)
		return FWTS_OUT_OF_MEMORY;
	fwts_settings->fw = fw;

	if (fw->pm_method == FWTS_PM_UNDEFINED) {
		/* Autodetection */
		fwts_log_info(fw, "Detecting the power method.");
		detect_pm_method(fwts_settings);
	}

	switch (fw->pm_method) {
#if FWTS_ENABLE_LOGIND
		case FWTS_PM_LOGIND:
			fwts_log_info(fw, "Using logind as the default power method.");
			if (fwts_logind_init_proxy(fwts_settings) != 0) {
				fwts_log_error(fw, "Failure to connect to Logind.");
				rc = FWTS_ERROR;
				goto tidy;
			}
			do_s4 = &wrap_logind_do_s4;
			break;
#endif
		case FWTS_PM_PMUTILS:
			fwts_log_info(fw, "Using pm-utils as the default power method.");
			do_s4 = &wrap_pmutils_do_s4;
			break;
		case FWTS_PM_SYSFS:
			fwts_log_info(fw, "Using sysfs as the default power method.");
			do_s4 = &wrap_sysfs_do_s4;
			break;
		default:
			/* This should never happen */
			fwts_log_info(fw, "Using sysfs as the default power method.");
			do_s4 = &wrap_sysfs_do_s4;
			break;
	}

	if (s4_device_check)
		fwts_hwinfo_get(fw, &hwinfo1);

	if (fw->pm_method == FWTS_PM_PMUTILS) {
		/* Format up pm-hibernate command with optional quirking arguments */
		if ((command = fwts_realloc_strcat(NULL, PM_HIBERNATE)) == NULL) {
			rc = FWTS_OUT_OF_MEMORY;
			goto tidy;
		}

		/* For now we only support quirks with pm-utils */
		if (s4_quirks) {
			if ((command = fwts_realloc_strcat(command, " ")) == NULL) {
				rc = FWTS_OUT_OF_MEMORY;
				goto tidy;
			}
			if ((quirks = fwts_args_comma_list(s4_quirks)) == NULL) {
				rc = FWTS_OUT_OF_MEMORY;
				goto tidy;
			}
			if ((command = fwts_realloc_strcat(command, quirks)) == NULL) {
				rc = FWTS_OUT_OF_MEMORY;
				goto tidy;
			}
		}
	}

	fwts_wakealarm_trigger(fw, s4_sleep_delay);

	/* Do s4 here */
	if ((klog_pre = fwts_klog_read()) == NULL)
		fwts_log_error(fw, "S4: hibernate: Cannot read kernel log.");

	status = do_s4(fwts_settings, percent, &duration, command);

	if ((klog_post = fwts_klog_read()) == NULL)
		fwts_log_error(fw, "S4: hibernate: Cannot re-read kernel log.");

	if (s4_device_check) {
		int i;

		for (i = 0; i < s4_device_check_delay; i++) {
			char buffer[80];

			snprintf(buffer, sizeof(buffer), "(Waiting %d/%d seconds)", i+1, s4_device_check_delay);
			fwts_progress_message(fw, percent, buffer);
			sleep(1);
		}
		fwts_progress_message(fw, percent, "(Checking devices)");
		fwts_hwinfo_get(fw, &hwinfo2);
		fwts_hwinfo_compare(fw, &hwinfo1, &hwinfo2, &differences);
		fwts_hwinfo_free(&hwinfo1);
		fwts_hwinfo_free(&hwinfo2);

		if (differences > 0) {
			fwts_failed(fw, LOG_LEVEL_HIGH, "DevConfigDiffAfterS4",
				"Found %d differences in device configuation during S4 cycle.", differences);
			(*hw_errors)++;
		}
	}

	fwts_progress_message(fw, percent, "(Checking for errors)");

	klog_diff = fwts_klog_find_changes(klog_pre, klog_post);
	s4_check_log(fw, klog_diff, klog_errors, klog_oopses, klog_warn_ons);

	fwts_progress_message(fw, percent, "(Checking for PM errors)");

	/* Add in error check for pm-hibernate status */
	if ((status > 0) && (status < 128)) {
		fwts_failed(fw, LOG_LEVEL_HIGH, "PMActionFailedPreS4",
			"pm-action failed before trying to put the system "
			"in the requested power saving state.");
		(*pm_errors)++;
	} else if (status == 128) {
		fwts_failed(fw, LOG_LEVEL_HIGH, "PMActionPowerStateS4",
			"pm-action tried to put the machine in the requested "
			"power state but failed.");
		(*pm_errors)++;
	} else if (status > 128) {
		fwts_failed(fw, LOG_LEVEL_HIGH, "PMActionFailedS4",
			"pm-action encountered an error and also failed to "
			"enter the requested power saving state.");
		(*pm_errors)++;
	}

	if (fwts_klog_regex_find(fw, klog_diff, "Freezing user space processes.*done") < 1) {
		fwts_failed(fw, LOG_LEVEL_HIGH, "UserSpaceTaskFreeze",
			"Failed to freeze user space processes.");
		(*pm_errors)++;
	}

	if (fwts_klog_regex_find(fw, klog_diff, "Freezing remaining freezable tasks.*done") < 1) {
		fwts_failed(fw, LOG_LEVEL_HIGH, "KernelTaskFreeze",
			"Failed to freeze remaining non-user space processes.");
		(*pm_errors)++;
	}

	if ((fwts_klog_regex_find(fw, klog_diff, "PM: freeze of devices complete") < 1) &&
	    (fwts_klog_regex_find(fw, klog_diff, "PM: late freeze of devices complete") < 1)) {
		fwts_failed(fw, LOG_LEVEL_HIGH, "DeviceFreeze",
			"Failed to freeze devices.");
		(*pm_errors)++;
	}

	if (fwts_klog_regex_find(fw, klog_diff, "PM: Allocated.*kbytes") < 1) {
		fwts_failed(fw, LOG_LEVEL_HIGH, "HibernateImageAlloc",
			"Failed to allocate memory for hibernate image.");
		*failed_alloc_image = 1;
		(*pm_errors)++;
	}

	if (fwts_klog_regex_find(fw, klog_diff, "PM: Image restored successfully") < 1) {
		fwts_failed(fw, LOG_LEVEL_HIGH, "HibernateImageRestore",
			"Failed to restore hibernate image.");
		(*pm_errors)++;
	}

	fwts_klog_free(klog_pre);
	fwts_klog_free(klog_post);
	fwts_list_free(klog_diff, NULL);
tidy:
	free(command);
	free(quirks);
	free_pm_method_vars(fwts_settings);

	return rc;
}
Example #5
0
File: crs.c Project: 9elements/fwts
static int crs_test1(fwts_framework *fw)
{
	fwts_list *klog;
	int day, mon, year;
	char *cmdline;

	if ((cmdline = fwts_get("/proc/cmdline")) == NULL) {
		fwts_log_error(fw, "Cannot read /proc/cmdline");
		return FWTS_ERROR;
	}

	if (crs_get_bios_date(fw, &day, &mon, &year) != FWTS_OK) {
		fwts_log_error(fw, "Cannot determine age of BIOS.");
		free(cmdline);
		return FWTS_ERROR;
	}

	if ((klog = fwts_klog_read()) == NULL) {
		fwts_log_error(fw, "Cannot read kernel log.");
		free(cmdline);
		return FWTS_ERROR;
	}

        if (fwts_klog_regex_find(fw, klog,
		"PCI: Ignoring host bridge windows from ACPI;") > 0) {
		if (strstr(cmdline, "pci=nocrs") != NULL) {
			fwts_skipped(fw, "Kernel was booted with pci=nocrs, Ignoring host bridge windows _CRS settings from ACPI, skipping test.");
		}
		else {
			if (year == 0) {
				fwts_failed(fw, LOG_LEVEL_MEDIUM,
					"BIOSTooOld",
					"The kernel could not determine the BIOS age "
					"and has assumed that your BIOS is too old to correctly "
					"specify the host bridge MMIO aperture using _CRS.");
				fwts_log_advice(fw, "You can override this by booting with \"pci=use_crs\".");
			} else if (year < 2008) {
				fwts_passed(fw,
					"The kernel has detected an old BIOS (%d/%d/%d) "
					"and has assumed that your BIOS is too old to correctly "
					"specify the host bridge MMIO aperture using _CRS.", mon, day, year);
				fwts_log_advice(fw, "You can override this by booting with \"pci=use_crs\".");
			} else {
				fwts_failed(fw, LOG_LEVEL_MEDIUM,
					"HostBridgeWindows",
					"The kernel is ignoring host bridge windows from ACPI for some unknown reason. "
					"pci=nocrs has not been used as a boot parameter and the BIOS may be recent enough "
					"to support this (%d/%d/%d)", mon, day, year);
			}
		}
	} else if (fwts_klog_regex_find(fw, klog, "PCI: Using host bridge windows from ACPI;") > 0) {
		if (strstr(cmdline, "pci=use_crs") != NULL) {
			if (year == 0)  {
				fwts_failed(fw, LOG_LEVEL_MEDIUM,
					"BIOSNoReleaseDate",
					"The BIOS does not seem to have release date, hence pci=use_crs was required.");
			} else if (year < 2008) {
				fwts_passed(fw,
					"The BIOS is relatively old (%d/%d/%d) and hence pci=use_crs was required to "
					"enable host bridge windows _CRS settings from ACPI.", mon, day, year);
			} else {
				fwts_failed(fw, LOG_LEVEL_LOW,
					"BIOSSupportBridgeWindows",
					"Kernel was booted with pci=use_crs but this may be uncessary as "
					"the BIOS is new enough to support automatic bridge windows configuring using _CRS from ACPI. "
					"However, the workaround may be necessary because _CRS is incorrect or not implemented in the "
					"DSDT.");
			}
		}
		else {
			fwts_passed(fw,
				"The kernel has detected a BIOS newer than the end of 2007 (%d/%d/%d) "
				"and has assumed that your BIOS can correctly "
				"specify the host bridge MMIO aperture using _CRS.  If this does not work "
				"correctly you can override this by booting with \"pci=nocrs\".", mon, day, year);
		}
	} else {
		fwts_skipped(fw, "Cannot find host bridge message in kernel log, skipping test.");
	}

	fwts_list_free(klog, free);
	free(cmdline);

	return FWTS_OK;
}
Example #6
0
static int get_mtrrs(void)
{
	struct mtrr_entry *entry;
	FILE *fp;
	char line[4096];

	if ((mtrr_list = fwts_list_new()) == NULL)
		return FWTS_ERROR;

	if ((fp = fopen("/proc/mtrr", "r")) == NULL) {
		fwts_list_free(mtrr_list, free);
		return FWTS_ERROR;
	}

	while (!feof(fp)) {
		char *ptr1, *ptr2;

		if (fgets(line, sizeof(line), fp) == NULL)
			break;

		if ((entry = calloc(1, sizeof(struct mtrr_entry))) == NULL) {
			fwts_list_free(mtrr_list, free);
			fclose(fp);
			return FWTS_ERROR;
		}

		/*
		 * Put all text to lower case since the output
		 * from /proc/mtrr is variable upper/lower case
		 * across kernel versions so forcing to lower
		 * saves comparing for upper/lower case variants.
		 */
		for (ptr1 = line; *ptr1; ptr1++)
			*ptr1 = tolower(*ptr1);

		/* Parse the following:
		 *   reg01: base=0x080000000 ( 2048MB), size= 1024MB, count=1: write-back
		 */

		/* Get register, in decimal  */
		if (strncmp(line, "reg", 3)) {
			free(entry);
			continue;
		}
		entry->reg = strtoul(line + 3, NULL, 10);

		/* Get base, in hex */
		if ((ptr1 = strstr(line, "base=0x")) == NULL) {
			free(entry);
			continue;
		}
		entry->start = strtoull(ptr1 + 5, NULL, 16);

		/* Get size, in decimal */
		if ((ptr1 = strstr(line, "size=")) == NULL) {
			free(entry);
			continue;
		}

		entry->size = strtoull(ptr1 + 5, &ptr2, 10);
		if (ptr2 && (*ptr2 == 'm'))
			entry->size *= 1024 * 1024;
		if (ptr2 && (*ptr2 == 'k'))
			entry->size *= 1024;

		entry->end = entry->start + entry->size;

		if (strstr(line, "write-back"))
			entry->type = WRITE_BACK;
		else if (strstr(line, "uncachable"))
			entry->type = UNCACHED;
		else if (strstr(line, "write-through"))
			entry->type = WRITE_THROUGH;
		else if (strstr(line, "write-combining"))
			entry->type = WRITE_COMBINING;
		else if (strstr(line, "write-protect"))
			entry->type = WRITE_PROTECT;
		else entry->type = UNKNOWN;

		fwts_list_append(mtrr_list, entry);
	}
	fclose(fp);

	return FWTS_OK;
}