Hi,

attached patch adds another column into "Software settings in need of tuning" table in HTML output. This column contains command needed to tune the Tunables to fix the bad state.

Without that, it's not possible to find out what exactly is bad and how the device (software setting) should be tuned to perform better. Currently admins have to read the source code and then try to find out a way how to fix bad tunables with common commands. With this patch it's much more easier to do that.

Thanks for accepting,
Jan Kaluza
diff --git a/tuning/bluetooth.cpp b/tuning/bluetooth.cpp
index 3957316..cc98642 100644
--- a/tuning/bluetooth.cpp
+++ b/tuning/bluetooth.cpp
@@ -46,6 +46,8 @@
 bt_tunable::bt_tunable(void) : tunable("", 1.0, "Good", "Bad", "Unknown")
 {
 	sprintf(desc, _("Bluetooth device interface status"));
+	strcpy(toggle_bad, "/usr/sbin/hciconfig hci0 up &> /dev/null &");
+	strcpy(toggle_good, "/usr/sbin/hciconfig hci0 down &> /dev/null");
 }
 
 
@@ -180,6 +182,16 @@ void bt_tunable::toggle(void)
 	system("/usr/sbin/hciconfig hci0 down &> /dev/null");
 }
 
+const char *bt_tunable::toggle_script(void)
+{
+	int good;
+	good = good_bad();
+
+	if (good == TUNE_GOOD) {
+		return toggle_bad;
+	}
+	return toggle_good;
+}
 
 
 void add_bt_tunable(void)
diff --git a/tuning/bluetooth.h b/tuning/bluetooth.h
index 27e15f1..ecb667d 100644
--- a/tuning/bluetooth.h
+++ b/tuning/bluetooth.h
@@ -39,6 +39,8 @@ public:
 
 	virtual void toggle(void);
 
+	virtual const char *toggle_script(void);
+
 };
 
 extern void add_bt_tunable(void);
diff --git a/tuning/cpufreq.cpp b/tuning/cpufreq.cpp
index bf2b8ae..3d0dbea 100644
--- a/tuning/cpufreq.cpp
+++ b/tuning/cpufreq.cpp
@@ -35,6 +35,7 @@
 #include <unistd.h> 
 #include <dirent.h>
 #include <errno.h>
+#include <sys/stat.h>
 
 #include "../lib.h"
 #include "cpufreq.h"
@@ -153,6 +154,54 @@ void cpufreq_tunable::toggle(void)
 	closedir(dir);
 }
 
+const char *cpufreq_tunable::toggle_script(void) {
+	DIR *dir;
+	struct dirent *dirent;
+	FILE *file;
+	char filename[PATH_MAX];
+	char tmp[4096];
+	struct stat statbuf;
+	int good;
+	good = good_bad();
+
+	strcpy(toggle_good, "/sbin/modprobe cpufreq_ondemand > /dev/null 2>&1\n");
+
+	if (good == TUNE_GOOD) {
+		dir = opendir("/sys/devices/system/cpu");
+		if (!dir)
+			return NULL;
+
+		while ((dirent = readdir(dir))) {
+			if (dirent->d_name[0]=='.')
+				continue;
+			sprintf(filename, "/sys/devices/system/cpu/%s/cpufreq/scaling_governor", dirent->d_name);
+			if (stat(filename, &statbuf) == -1)
+				continue;
+			sprintf(tmp, "echo '%s' > '%s';\n", original, filename);
+			strcat(toggle_good, tmp);
+		}
+
+		closedir(dir);
+		return toggle_good;
+	}
+
+	dir = opendir("/sys/devices/system/cpu");
+	if (!dir)
+		return NULL;
+
+	while ((dirent = readdir(dir))) {
+		if (dirent->d_name[0]=='.')
+			continue;
+		sprintf(filename, "/sys/devices/system/cpu/%s/cpufreq/scaling_governor", dirent->d_name);
+		if (stat(filename, &statbuf) == -1)
+			continue;
+		sprintf(tmp, "echo 'ondemand' > '%s';\n", filename);
+		strcat(toggle_good, tmp);
+	}
+
+	closedir(dir);
+	return toggle_good;
+}
 
 
 void add_cpufreq_tunable(void)
diff --git a/tuning/cpufreq.h b/tuning/cpufreq.h
index 55af71f..983f813 100644
--- a/tuning/cpufreq.h
+++ b/tuning/cpufreq.h
@@ -40,6 +40,8 @@ public:
 
 	virtual void toggle(void);
 
+	virtual const char *toggle_script(void);
+
 };
 
 extern void add_cpufreq_tunable(void);
diff --git a/tuning/ethernet.cpp b/tuning/ethernet.cpp
index 4666ac1..7687e38 100644
--- a/tuning/ethernet.cpp
+++ b/tuning/ethernet.cpp
@@ -54,6 +54,8 @@ ethernet_tunable::ethernet_tunable(const char *iface) : tunable("", 0.3, _("Good
 	memset(interf, 0, sizeof(interf));
 	strncpy(interf, iface, sizeof(interf));
 	sprintf(desc, _("Wake-on-lan status for device %s"), iface);
+	sprintf(toggle_good, "ethtool -s %s wol d;", iface);
+	
 }
 
 
@@ -128,6 +130,18 @@ void ethernet_tunable::toggle(void)
 	close(sock);
 }
 
+const char *ethernet_tunable::toggle_script(void)
+{
+	int good;
+	good = good_bad();
+
+	if (good != TUNE_GOOD) {
+		return toggle_good;
+	}
+
+	return NULL;
+}
+
 
 void ethtunable_callback(const char *d_name)
 {
diff --git a/tuning/ethernet.h b/tuning/ethernet.h
index eeb6ebb..85810fb 100644
--- a/tuning/ethernet.h
+++ b/tuning/ethernet.h
@@ -40,6 +40,8 @@ public:
 
 	virtual void toggle(void);
 
+	virtual const char *toggle_script(void);
+
 };
 
 extern void add_ethernet_tunable(void);
diff --git a/tuning/runtime.cpp b/tuning/runtime.cpp
index 03cfa0b..3c6dae8 100644
--- a/tuning/runtime.cpp
+++ b/tuning/runtime.cpp
@@ -77,6 +77,8 @@ runtime_tunable::runtime_tunable(const char *path, const char *bus, const char *
 
 		
 	}
+	sprintf(toggle_good, "echo 'auto' > '%s';", runtime_path);
+	sprintf(toggle_bad, "echo 'on' > '%s';", runtime_path);
 }
 
 int runtime_tunable::good_bad(void)
@@ -105,6 +107,18 @@ void runtime_tunable::toggle(void)
 	write_sysfs(runtime_path, "auto");
 }
 
+const char *runtime_tunable::toggle_script(void)
+{
+	int good;
+	good = good_bad();
+
+	if (good == TUNE_GOOD) {
+		return toggle_bad;
+	}
+
+	return toggle_good;
+}
+
 
 void add_runtime_tunables(const char *bus)
 {
diff --git a/tuning/runtime.h b/tuning/runtime.h
index c874241..a3c3e20 100644
--- a/tuning/runtime.h
+++ b/tuning/runtime.h
@@ -39,6 +39,8 @@ public:
 
 	virtual void toggle(void);
 
+	virtual const char *toggle_script(void);
+
 };
 
 extern void add_runtime_tunables(const char *bus);
diff --git a/tuning/sysfs.cpp b/tuning/sysfs.cpp
index e1742a3..ffb2df0 100644
--- a/tuning/sysfs.cpp
+++ b/tuning/sysfs.cpp
@@ -39,6 +39,8 @@ sysfs_tunable::sysfs_tunable(const char *str, const char *_sysfs_path, const cha
 	strcpy(sysfs_path, _sysfs_path);
 	strcpy(target_value, _target_content);
 	bad_value[0] = 0;
+	sprintf(toggle_good, "echo '%s' > '%s';", target_value, sysfs_path);
+	sprintf(toggle_bad, "echo '%s' > '%s';", bad_value, sysfs_path);
 }
 
 int sysfs_tunable::good_bad(void)
@@ -77,6 +79,19 @@ void sysfs_tunable::toggle(void)
 	write_sysfs(sysfs_path, target_value);
 }
 
+const char *sysfs_tunable::toggle_script(void) {
+	int good;
+	good = good_bad();
+
+	if (good == TUNE_GOOD) {
+		if (strlen(bad_value) > 0)
+			return toggle_bad;
+		return NULL;
+	}
+
+	return toggle_good;
+}
+
 
 void add_sysfs_tunable(const char *str, const char *_sysfs_path, const char *_target_content)
 {
diff --git a/tuning/sysfs.h b/tuning/sysfs.h
index 9fee4c0..ac7938c 100644
--- a/tuning/sysfs.h
+++ b/tuning/sysfs.h
@@ -42,6 +42,8 @@ public:
 
 	virtual void toggle(void);
 
+	virtual const char *toggle_script(void);
+
 };
 
 extern void add_sysfs_tunable(const char *str, const char *_sysfs_path, const char *_target_content);
diff --git a/tuning/tunable.h b/tuning/tunable.h
index a4e994d..dacbd79 100644
--- a/tuning/tunable.h
+++ b/tuning/tunable.h
@@ -42,6 +42,9 @@ class tunable {
 	char good_string[128];
 	char bad_string[128];
 	char neutral_string[128];
+protected:
+	char toggle_good[4096];
+	char toggle_bad[4096];
 public:
 	char desc[4096];
 	double score;
@@ -67,6 +70,8 @@ public:
 	virtual const char *description(void) { return desc; };
 
 	virtual void toggle(void) { };
+
+	virtual const char *toggle_script(void) { return NULL; }
 };
 
 extern vector<class tunable *> all_tunables;
diff --git a/tuning/tuning.cpp b/tuning/tuning.cpp
index c63f1e8..dd5b1dc 100644
--- a/tuning/tuning.cpp
+++ b/tuning/tuning.cpp
@@ -218,7 +218,7 @@ void html_show_tunables(void)
 		}
 
 		line++;
-		fprintf(htmlout, "<tr class=\"%s\"><td>%s</td></tr>\n", tune_class_bad(line), all_tunables[i]->description());
+		fprintf(htmlout, "<tr class=\"%s\"><td>%s</td><td>%s</td></tr>\n", tune_class_bad(line), all_tunables[i]->description(), all_tunables[i]->toggle_script());
 	}
 
 	if (line > 0) 
diff --git a/tuning/usb.cpp b/tuning/usb.cpp
index 16e25d4..6bcfb07 100644
--- a/tuning/usb.cpp
+++ b/tuning/usb.cpp
@@ -74,6 +74,9 @@ usb_tunable::usb_tunable(const char *path, const char *name) : tunable("", 0.9,
 		sprintf(desc, _("Autosuspend for USB device %s [%s]"), product, name);
 	else if (strlen(vendor))
 		sprintf(desc, _("Autosuspend for USB device %s [%s]"), vendor, name);
+
+	sprintf(toggle_good, "echo 'auto' > '%s';", usb_path);
+	sprintf(toggle_bad, "echo 'on' > '%s';", usb_path);
 }
 
 int usb_tunable::good_bad(void)
@@ -102,6 +105,17 @@ void usb_tunable::toggle(void)
 	write_sysfs(usb_path, "auto");
 }
 
+const char *usb_tunable::toggle_script(void)
+{
+	int good;
+	good = good_bad();
+
+	if (good == TUNE_GOOD) {
+		return toggle_bad;
+	}
+
+	return toggle_good;
+}
 
 void add_usb_tunables(void)
 {
diff --git a/tuning/usb.h b/tuning/usb.h
index a6f9557..a257904 100644
--- a/tuning/usb.h
+++ b/tuning/usb.h
@@ -40,6 +40,8 @@ public:
 
 	virtual void toggle(void);
 
+	virtual const char *toggle_script(void);
+
 };
 
 extern void add_usb_tunables(void);
diff --git a/tuning/wifi.cpp b/tuning/wifi.cpp
index 9d64a9f..8b67fc5 100644
--- a/tuning/wifi.cpp
+++ b/tuning/wifi.cpp
@@ -46,6 +46,9 @@ wifi_tunable::wifi_tunable(const char *_iface) : tunable("", 1.5, _("Good"), _("
 {
 	strcpy(iface, _iface);
 	sprintf(desc, _("Wireless Power Saving for interface %s"), iface);
+	
+	sprintf(toggle_good, "iw dev %s set power_save off", iface);
+	sprintf(toggle_bad, "iw dev %s set power_save on", iface);
 }
 
 int wifi_tunable::good_bad(void)
@@ -69,6 +72,17 @@ void wifi_tunable::toggle(void)
 	set_wifi_power_saving(iface, 1);
 }
 
+const char *wifi_tunable::toggle_script(void)
+{
+	int good;
+	good = good_bad();
+
+	if (good == TUNE_GOOD) {
+		return toggle_bad;
+	}
+
+	return toggle_good;
+}
 
 void add_wifi_tunables(void)
 {
diff --git a/tuning/wifi.h b/tuning/wifi.h
index 347470e..50ca68c 100644
--- a/tuning/wifi.h
+++ b/tuning/wifi.h
@@ -40,6 +40,8 @@ public:
 
 	virtual void toggle(void);
 
+	virtual const char *toggle_script(void);
+
 };
 
 extern void add_wifi_tunables(void);
_______________________________________________
Power mailing list
Power@bughost.org
https://bughost.org/mailman/listinfo/power

Reply via email to