system: Add support for getting/setting i/o priorities and include a userspace tool

Signed-off-by: San Mehat <san@google.com>
diff --git a/include/cutils/iosched_policy.h b/include/cutils/iosched_policy.h
new file mode 100644
index 0000000..07c5d1f
--- /dev/null
+++ b/include/cutils/iosched_policy.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CUTILS_IOSCHED_POLICY_H
+#define __CUTILS_IOSCHED_POLICY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    IoSchedClass_NONE,
+    IoSchedClass_RT,
+    IoSchedClass_BE,
+    IoSchedClass_IDLE,
+} IoSchedClass;
+
+extern int android_set_ioprio(int pid, IoSchedClass clazz, int ioprio);
+extern int android_get_ioprio(int pid, IoSchedClass *clazz, int *ioprio);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CUTILS_IOSCHED_POLICY_H */ 
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 93933e2..4c45cc9 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -38,7 +38,8 @@
 	process_name.c \
 	properties.c \
 	threads.c \
-	sched_policy.c
+	sched_policy.c \
+	iosched_policy.c
 
 commonHostSources := \
         ashmem-host.c
diff --git a/libcutils/iosched_policy.c b/libcutils/iosched_policy.c
new file mode 100644
index 0000000..4004a2a
--- /dev/null
+++ b/libcutils/iosched_policy.c
@@ -0,0 +1,61 @@
+
+/* libs/cutils/iosched_policy.c
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/unistd.h>
+
+#ifdef HAVE_SCHED_H
+
+#include <cutils/iosched_policy.h>
+
+extern int ioprio_set(int which, int who, int ioprio);
+
+enum {
+    WHO_PROCESS = 1,
+    WHO_PGRP,
+    WHO_USER,
+};
+
+#define CLASS_SHIFT 13
+#define IOPRIO_NORM 4
+
+int android_set_ioprio(int pid, IoSchedClass clazz, int ioprio) {
+    if (ioprio_set(WHO_PROCESS, pid, ioprio | (clazz << CLASS_SHIFT))) {
+        return -1;
+    }
+    return 0;
+}
+
+int android_get_ioprio(int pid, IoSchedClass *clazz, int *ioprio) {
+    int rc;
+
+    if ((rc = ioprio_get(WHO_PROCESS, pid)) < 0) {
+        return -1;
+    }
+
+    *clazz = (rc >> CLASS_SHIFT);
+    *ioprio = (rc & 0xff);
+    return 0;
+}
+
+#endif /* HAVE_SCHED_H */
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 122a544..a6114ac 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -51,7 +51,8 @@
 	iftop \
 	id \
 	vmstat \
-	nandread
+	nandread \
+        ionice
 
 LOCAL_SRC_FILES:= \
 	toolbox.c \
diff --git a/toolbox/ionice.c b/toolbox/ionice.c
new file mode 100644
index 0000000..4a182f2
--- /dev/null
+++ b/toolbox/ionice.c
@@ -0,0 +1,57 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <cutils/iosched_policy.h>
+
+static char *classes[] = {"none", "rt", "be", "idle", NULL};
+
+int ionice_main(int argc, char *argv[])
+{
+    IoSchedClass clazz = IoSchedClass_NONE;
+    int ioprio = 0;
+    int pid;
+
+    if(argc != 2 && argc != 4) {
+        fprintf(stderr, "usage: ionice <pid> [none|rt|be|idle] [prio]\n");
+        return 1;
+    }
+
+    if (!(pid = atoi(argv[1]))) {
+        fprintf(stderr, "Invalid pid specified\n");
+        return 1;
+    }
+
+    if (argc == 2) {
+        if (android_get_ioprio(pid, &clazz, &ioprio)) {
+            fprintf(stderr, "Failed to read priority (%s)\n", strerror(errno));
+            return 1;
+        }
+        fprintf(stdout, "Pid %d, class %s (%d), prio %d\n", pid, classes[clazz], clazz, ioprio);
+        return 0;
+    }
+
+    if (!strcmp(argv[2], "none")) {
+        clazz = IoSchedClass_NONE;
+    } else if (!strcmp(argv[2], "rt")) {
+        clazz = IoSchedClass_RT;
+    } else if (!strcmp(argv[2], "be")) {
+        clazz = IoSchedClass_BE;
+    } else if (!strcmp(argv[2], "idle")) {
+        clazz = IoSchedClass_IDLE;
+    } else {
+        fprintf(stderr, "Unsupported class '%s'\n", argv[2]);
+        return 1;
+    }
+
+    ioprio = atoi(argv[3]);
+
+    printf("Setting pid %d i/o class to %d, prio %d\n", pid, clazz, ioprio);
+    if (android_set_ioprio(pid, clazz, ioprio)) {
+        fprintf(stderr, "Failed to set priority (%s)\n", strerror(errno));
+        return 1;
+    }
+
+    return 0;
+}