Fields to change IO class and priority
authorJamie Cameron <jcameron@webmin.com>
Sun, 8 Jun 2008 22:00:51 +0000 (22:00 +0000)
committerJamie Cameron <jcameron@webmin.com>
Sun, 8 Jun 2008 22:00:51 +0000 (22:00 +0000)
proc/CHANGELOG
proc/edit_proc.cgi
proc/lang/en
proc/linux-lib.pl
proc/renice_proc.cgi

index c451c6e..5f614a1 100644 (file)
@@ -17,3 +17,6 @@ Re-wrote the user interface using the new Webmin UI library, for consistency.
 Re-designed the Run and Search pages, and made the search radio buttons auto-selecting.
 ---- Changes since 1.410 ----
 Added physical memory display on FreeBSD.
+---- Changes since 1.420 ----
+Corrected physical memory display on FreeBSD.
+On Linux systems with the ionice command, the IO scheduling class and priority of running processes can be edited.
index c524c23..bc8fbb0 100755 (executable)
@@ -54,6 +54,23 @@ print &ui_table_row(&hlink($text{'nice'},"nice"),
        &indexof($pinfo{nice}, @nice_range) < 0 ? $pinfo{nice} :
                &nice_selector("nice", $pinfo{nice}).
                &ui_submit($text{'edit_change'}), 3);
+
+# IO scheduling class, if support
+if (defined(&os_list_scheduling_classes) &&
+    (@classes = &os_list_scheduling_classes())) {
+       ($class, $prio) = &os_get_scheduling_class($pinfo{'pid'});
+       ($got) = grep { $_->[0] == $class } @classes;
+       if (!$got) {
+               # Some unknown class, probably 'none'
+               unshift(@classes, [ $class, $text{'default'} ]);
+               }
+       print &ui_table_row(&hlink($text{'sclass'},"sclass"),
+               &ui_select("sclass", $class, \@classes));
+       print &ui_table_row(&hlink($text{'sprio'},"sprio"),
+               &ui_select("sprio", $prio,
+                          [ &os_list_scheduling_priorities() ], 1, 0, 1));
+       }
+
 print &ui_form_end();
 
 # Extra OS-specific info
index 36008ef..46baf66 100644 (file)
@@ -24,6 +24,8 @@ parent=Parent process
 runtime=Run time
 nice=Nice level
 stime=Started
+sclass=IO scheduling class
+sprio=IO priority
 
 search_user=Owned by
 search_match=Matching
@@ -101,6 +103,10 @@ linuxstat_D=Deep sleep
 linuxstat_T=Stopped
 linuxstat_Z=Zombie
 
+linux_real=Real time
+linux_be=Best effort
+linux_idle=Idle
+
 freebsd_ruser=Real user
 freebsd_rgroup=Real group
 freebsd_tty=TTY
index e39a0a9..14550ff 100644 (file)
@@ -360,5 +360,54 @@ foreach $ia (keys %text) {
 
 $has_fuser_command = 1;
 
+# os_list_scheduling_classes()
+# Returns a list of Linux scheduling classes, if supported. Each element is a
+# 2-element array ref containing a code and description.
+sub os_list_scheduling_classes
+{
+if (&has_command("ionice")) {
+       return ( [ 1, $text{'linux_real'} ],
+                [ 2, $text{'linux_be'} ],
+                [ 3, $text{'linux_idle'} ] );
+       }
+return ( );
+}
+
+# os_list_scheduling_priorities()
+# Returns a list of IO priorities, each of which is an array ref containing
+# a number and description
+sub os_list_scheduling_priorities
+{
+return ( [ 0, "0 ($text{'edit_prihigh'})" ],
+        [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ], [ 6 ],
+        [ 7, "7 ($text{'edit_prilow'})" ] );
+}
+
+# os_get_scheduling_class(pid)
+# Returns the IO scheduling class and priority for a running program
+sub os_get_scheduling_class
+{
+local ($pid) = @_;
+local $out = &backquote_command("ionice -p ".quotemeta($pid));
+if ($out =~ /^(realtime|best-effort|idle|none):\s+prio\s+(\d+)/) {
+       return ($1 eq "realtime" ? 1 : $1 eq "best-effort" ? 2 :
+               $1 eq "idle" ? 3 : 0, $2);
+       }
+return ( );
+}
+
+# os_set_scheduling_class(pid, class, priority)
+# Sets the ID scheduling class and priority for some process. Returns an error
+# message on failure, undef on success.
+sub os_set_scheduling_class
+{
+local ($pid, $class, $prio) = @_;
+local $cmd = "ionice -c ".quotemeta($class);
+$cmd .= " -n ".quotemeta($prio) if (defined($prio));
+$cmd .= " -p ".quotemeta($pid);
+local $out = &backquote_logged("$cmd 2>&1 </dev/null");
+return $? ? $out : undef;
+}
+
 1;
 
index e944303..ae05b21 100755 (executable)
@@ -1,16 +1,25 @@
 #!/usr/local/bin/perl
 # renice_proc.cgi
-# Change the nice level of a process
+# Change the nice level of a process, and possibly the IO scheduling
 
 require './proc-lib.pl';
 &ReadParse();
 &switch_acl_uid();
 &error_setup(&text('renice_err', $in{pid}));
 %pinfo = &process_info($in{pid});
+
+# Set nice level
 &can_edit_process($pinfo{'user'}) || &error($text{'renice_ecannot'});
-if ($error = &renice_proc($in{pid}, $in{nice})) {
+if ($error = &renice_proc($in{'pid'}, $in{nice})) {
        &error($error);
        }
+
+# Set IO scheduling
+if (defined($in{'sclass'})) {
+       $error = &os_set_scheduling_class(
+               $in{'pid'}, $in{'sclass'}, $in{'sprio'});
+       }
+
 &webmin_log("renice", undef, undef, \%in);
 &redirect("edit_proc.cgi?$in{pid}");