-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - [EMAIL PROTECTED]   |      .......you may get it.
----------------------------------------------------------------------
Part 1 of 5 patches to support Rule Based Classification Engine for CKRM.
This patch provides the the basic rcfs interface for rbce. It just provides
the interface with stub functions.

Signed-Off-By: Hubertus Franke <[EMAIL PROTECTED]>
Signed-Off-By: Chandra Seetharaman <[EMAIL PROTECTED]>
Signed-Off-By: Shailabh Nagar <[EMAIL PROTECTED]>
Signed-Off-By: Vivek Kashyap <[EMAIL PROTECTED]>
Signed-Off-By: Gerrit Huizenga <[EMAIL PROTECTED]>

 include/linux/rbce.h             |   28 ++
 init/Kconfig                     |   12 +
 kernel/ckrm/Makefile             |    1 
 kernel/ckrm/rbce/Makefile        |    6 
 kernel/ckrm/rbce/rbce_fs.c       |  378 +++++++++++++++++++++++++++++++++++++++
 kernel/ckrm/rbce/rbce_info.h     |   78 ++++++++
 kernel/ckrm/rbce/rbce_internal.h |   68 +++++++
 kernel/ckrm/rbce/rbce_main.c     |   99 ++++++++++
 8 files changed, 670 insertions(+)

Index: linux-2.6.12-rc1/include/linux/rbce.h
===================================================================
--- /dev/null
+++ linux-2.6.12-rc1/include/linux/rbce.h
@@ -0,0 +1,28 @@
+/* Rule-based Classification Engine (RBCE) module
+ *
+ * Copyright (C) Hubertus Franke, IBM Corp. 2003
+ *           (C) Chandra Seetharaman, IBM Corp. 2003
+ * 
+ * Module for loading of classification policies and providing
+ * a user API for Class-based Kernel Resource Management (CKRM)
+ *
+ * Latest version, more details at http://ckrm.sf.net
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * 
+ *
+ */
+
+#ifndef _LINUX_RBCE_H
+#define _LINUX_RBCE_H
+
+#define RBCE_MOD_DESCR "Rule Based Classification Engine Module for CKRM"
+#define RBCE_MOD_NAME  "rbce"
+
+#endif /* _LINUX_RBCE_H */
Index: linux-2.6.12-rc1/init/Kconfig
===================================================================
--- linux-2.6.12-rc1.orig/init/Kconfig
+++ linux-2.6.12-rc1/init/Kconfig
@@ -195,6 +195,18 @@ config CKRM_RES_NUMTASKS
        
          Say N if unsure, Y to use the feature.
 
+
+config CKRM_RBCE
+       tristate "Vanilla Rule-based Classification Engine (RBCE)"
+       depends on CKRM && RCFS_FS
+       default m
+       help
+         Provides an optional module to support creation of rules for automatic
+         classification of kernel objects. Rules are created/deleted/modified
+         through an rcfs interface. RBCE is not required for CKRM.
+
+         If unsure, say N.
+
 endmenu
 
 config SYSCTL
Index: linux-2.6.12-rc1/kernel/ckrm/Makefile
===================================================================
--- linux-2.6.12-rc1.orig/kernel/ckrm/Makefile
+++ linux-2.6.12-rc1/kernel/ckrm/Makefile
@@ -6,3 +6,4 @@ obj-y += ckrm_events.o ckrm.o ckrmutils.
 obj-$(CONFIG_CKRM_TYPE_TASKCLASS) += ckrm_tc.o ckrm_numtasks_stub.o
 obj-$(CONFIG_CKRM_TYPE_SOCKETCLASS) += ckrm_sockc.o
 obj-$(CONFIG_CKRM_RES_NUMTASKS) += ckrm_numtasks.o
+obj-$(CONFIG_CKRM_RBCE) += rbce/
Index: linux-2.6.12-rc1/kernel/ckrm/rbce/Makefile
===================================================================
--- /dev/null
+++ linux-2.6.12-rc1/kernel/ckrm/rbce/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for RBCE
+#
+
+obj-$(CONFIG_CKRM_RBCE)        += rbce.o
+rbce-objs := rbce_fs.o rbce_main.o
Index: linux-2.6.12-rc1/kernel/ckrm/rbce/rbce_fs.c
===================================================================
--- /dev/null
+++ linux-2.6.12-rc1/kernel/ckrm/rbce/rbce_fs.c
@@ -0,0 +1,365 @@
+/*
+ * RCFS API for Rule-based Classification Engine (RBCE)
+ *
+ * Copyright (C) Hubertus Franke, IBM Corp. 2003
+ *           (C) Chandra Seetharaman, IBM Corp. 2003
+ *           (C) Vivek Kashyap, IBM Corp. 2004
+ *
+ * Module for loading of classification policies and providing
+ * a user API for Class-based Kernel Resource Management (CKRM)
+ *
+ * Latest version, more details at http://ckrm.sf.net
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#include <linux/pagemap.h>
+#include <linux/rcfs.h>
+#include "rbce_internal.h"
+
+#define CONFIG_CE_DIR          "ce"
+#define CONFIG_RULES_DIR       "rules"
+#define CONFIG_RBCE_STATE      "rbce_state"
+#define CONFIG_RBCE_TAG                "rbce_tag"
+
+static int rbce_unlink(struct inode *, struct dentry *);
+
+static ssize_t
+rbce_write(struct file *file, const char __user * buf,
+          size_t len, loff_t * ppos)
+{
+       char *line, *ptr;
+       int rc = 0, pid;
+
+       line = kmalloc(len + 1, GFP_KERNEL);
+       if (!line) {
+               return -ENOMEM;
+       }
+       if (copy_from_user(line, buf, len)) {
+               kfree(line);
+               return -EFAULT;
+       }
+       line[len] = '\0';
+       ptr = line;
+       while (*ptr) {
+               if (*ptr == '\n') {
+                       *ptr = '\0';
+                       break;
+               }
+               ptr++;
+       }
+       if (!strcmp(file->f_dentry->d_name.name, CONFIG_RBCE_TAG)) {
+               pid = simple_strtol(line, &ptr, 0);
+               rc = rbce_set_tasktag(pid, ptr + 1); /* syntax "pid tag" */
+       } else if (!strcmp(file->f_dentry->d_name.name, CONFIG_RBCE_STATE))
+               rbce_enabled = line[0] - '0';
+       else
+               rc = rbce_change_rule(file->f_dentry->d_name.name, line);
+       if (rc)
+               len = rc;
+       kfree(line);
+       return len;
+}
+
+static int rbce_show(struct seq_file *seq, void *offset)
+{
+       struct file *file = (struct file *)seq->private;
+       char result[256];
+
+       memset(result, 0, 256);
+       if (!strcmp(file->f_dentry->d_name.name, CONFIG_RBCE_TAG))
+               return -EPERM;
+       if (!strcmp(file->f_dentry->d_name.name, CONFIG_RBCE_STATE))
+               seq_printf(seq, "%d\n", rbce_enabled);
+       else {
+               rbce_get_rule(file->f_dentry->d_name.name, result);
+               seq_printf(seq, "%s\n", result);
+       }
+       return 0;
+}
+
+static int rbce_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, rbce_show, file);
+}
+
+static int rbce_close(struct inode *ino, struct file *file)
+{
+       const char *name = file->f_dentry->d_name.name;
+
+       if (strcmp(name, CONFIG_RBCE_STATE) &&
+                       strcmp(name, CONFIG_RBCE_TAG) &&
+                       !rbce_rule_exists(name))
+               rbce_unlink(file->f_dentry->d_parent->d_inode, file->f_dentry);
+       return single_release(ino, file);
+}
+
+static struct file_operations rbce_file_operations;
+static struct inode_operations rbce_file_inode_operations;
+static struct inode_operations rbce_dir_inode_operations;
+
+static struct inode *rbce_get_inode(struct inode *dir, int mode, dev_t dev)
+{
+       struct inode *inode = new_inode(dir->i_sb);
+
+       if (inode) {
+               inode->i_mode = mode;
+               inode->i_uid = current->fsuid;
+               inode->i_gid = current->fsgid;
+               inode->i_blksize = PAGE_CACHE_SIZE;
+               inode->i_blocks = 0;
+               inode->i_mapping->a_ops = dir->i_mapping->a_ops;
+               inode->i_mapping->backing_dev_info =
+                   dir->i_mapping->backing_dev_info;
+               inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+               switch (mode & S_IFMT) {
+               default:
+                       init_special_inode(inode, mode, dev);
+                       break;
+               case S_IFREG:
+                       /* Treat as default assignment */
+                       inode->i_op = &rbce_file_inode_operations;
+                       inode->i_fop = &rbce_file_operations;
+                       break;
+               case S_IFDIR:
+                       inode->i_op = &rbce_dir_inode_operations;
+                       inode->i_fop = &simple_dir_operations;
+
+                       /* directory inodes start off with i_nlink == 2
+                          (for "." entry) */
+                       inode->i_nlink++;
+                       break;
+               }
+       }
+       return inode;
+}
+
+/*
+ * File creation. Allocate an inode, and we're done..
+ */
+static int
+rbce_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+{
+       struct inode *inode = rbce_get_inode(dir, mode, dev);
+       int error = -ENOSPC;
+
+       if (inode) {
+               if (dir->i_mode & S_ISGID) {
+                       inode->i_gid = dir->i_gid;
+                       if (S_ISDIR(mode))
+                               inode->i_mode |= S_ISGID;
+               }
+               d_instantiate(dentry, inode);
+               dget(dentry);   /* Extra count - pin the dentry in core */
+               error = 0;
+
+       }
+       return error;
+}
+
+static int rbce_unlink(struct inode *dir, struct dentry *dentry)
+{
+       struct inode *inode = dentry->d_inode;
+       int rc;
+
+       rc = rbce_delete_rule(dentry->d_name.name);
+       if (rc == 0) {
+               if (dir)
+                       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+               inode->i_ctime = CURRENT_TIME;
+               inode->i_nlink--;
+               dput(dentry);
+       }
+       return rc;
+}
+
+static int
+rbce_rename(struct inode *old_dir, struct dentry *old_dentry,
+           struct inode *new_dir, struct dentry *new_dentry)
+{
+       int rc;
+       struct inode *inode = old_dentry->d_inode;
+       struct dentry *old_d = list_entry(old_dir->i_dentry.next,
+                                         struct dentry, d_alias);
+       struct dentry *new_d = list_entry(new_dir->i_dentry.next,
+                                         struct dentry, d_alias);
+
+       /* Do not allow renaming any directory */
+       if (S_ISDIR(old_dentry->d_inode->i_mode))
+               return -EINVAL;
+
+       /* Do not allow renaming files just under under /ce */
+       if (!strcmp(old_d->d_name.name, CONFIG_CE_DIR))
+               return -EINVAL;
+
+       /* cannot move anything to /ce */
+       if (!strcmp(new_d->d_name.name, CONFIG_CE_DIR))
+               return -EINVAL;
+
+       rc = rbce_rename_rule(old_dentry->d_name.name, new_dentry->d_name.name);
+
+       if (!rc)
+               old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime =
+                   new_dir->i_mtime = inode->i_ctime = CURRENT_TIME;
+       return rc;
+}
+
+/* CE allows only the rules directory to be created */
+int rbce_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+       int retval = -EINVAL;
+
+       struct dentry *pd =
+           list_entry(dir->i_dentry.next, struct dentry, d_alias);
+
+       /* Allow only /rcfs/ce and ce/rules */
+       if ((!strcmp(pd->d_name.name, CONFIG_CE_DIR) &&
+                       !strcmp(dentry->d_name.name, CONFIG_RULES_DIR)) ||
+                       (!strcmp(pd->d_name.name, "/") &&
+                       !strcmp(dentry->d_name.name, CONFIG_CE_DIR))) {
+               if (!strcmp(dentry->d_name.name, CONFIG_CE_DIR))
+                       try_module_get(THIS_MODULE);
+               retval = rbce_mknod(dir, dentry, mode | S_IFDIR, 0);
+               if (!retval)
+                       dir->i_nlink++;
+       }
+
+       return retval;
+}
+
+/* CE doesn't allow deletion of directory */
+int rbce_rmdir(struct inode *dir, struct dentry *dentry)
+{
+       int rc;
+       rc = simple_rmdir(dir, dentry);
+
+       if (!rc && !strcmp(dentry->d_name.name, CONFIG_CE_DIR))
+               module_put(THIS_MODULE);
+       return rc;
+}
+
+static int
+rbce_create(struct inode *dir, struct dentry *dentry,
+           int mode, struct nameidata *nd)
+{
+       struct dentry *pd =
+           list_entry(dir->i_dentry.next, struct dentry, d_alias);
+
+       /* No creation allowed under ce */
+       if (!strcmp(pd->d_name.name, CONFIG_CE_DIR))
+               return -EINVAL;
+
+       return rbce_mknod(dir, dentry, mode | S_IFREG, 0);
+}
+
+static int rbce_link(struct dentry *old_d, struct inode *dir, struct dentry *d)
+{
+       return -EINVAL;
+}
+
+static int
+rbce_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+{
+       return -EINVAL;
+}
+
+/******************************* Config files  ********************/
+
+#define RBCE_NR_CONFIG 5
+struct rcfs_magf rbce_config_files[RBCE_NR_CONFIG] = {
+       {
+        .name = CONFIG_CE_DIR,
+        .mode = RCFS_DEFAULT_DIR_MODE,
+        .i_op = &rbce_dir_inode_operations,
+        },
+       {
+        .name = CONFIG_RBCE_TAG,
+        .mode = RCFS_DEFAULT_FILE_MODE,
+        .i_fop = &rbce_file_operations,
+        },
+       {
+        .name = CONFIG_RBCE_STATE,
+        .mode = RCFS_DEFAULT_FILE_MODE,
+        .i_fop = &rbce_file_operations,
+        },
+       {
+        .name = CONFIG_RULES_DIR,
+        .mode = (RCFS_DEFAULT_DIR_MODE | S_IWUSR),
+        .i_fop = &simple_dir_operations,
+        .i_op = &rbce_dir_inode_operations,
+        }
+};
+
+static struct dentry *ce_root_dentry;
+
+int rbce_create_config(void)
+{
+       int rc;
+
+       /* Make root dentry */
+       rc = rcfs_mkroot(rbce_config_files, RBCE_NR_CONFIG, &ce_root_dentry);
+       if ((!ce_root_dentry) || rc)
+               return rc;
+
+       /* Create config files */
+       if ((rc = rcfs_create_magic(ce_root_dentry, &rbce_config_files[1],
+                                   RBCE_NR_CONFIG - 1))) {
+               printk(KERN_ERR "Failed to create c/rbce config files."
+                      " Deleting c/rbce root\n");
+               rcfs_rmroot(ce_root_dentry);
+               return rc;
+       }
+
+       return rc;
+}
+
+int rbce_clear_config(void)
+{
+       int rc = 0;
+       if (ce_root_dentry)
+               rc = rcfs_rmroot(ce_root_dentry);
+       return rc;
+}
+
+/******************************* File ops ********************/
+
+static struct file_operations rbce_file_operations = {
+       .owner = THIS_MODULE,
+       .open = rbce_open,
+       .llseek = seq_lseek,
+       .read = seq_read,
+       .write = rbce_write,
+       .release = rbce_close,
+};
+
+static struct inode_operations rbce_file_inode_operations = {
+       .getattr = simple_getattr,
+};
+
+static struct inode_operations rbce_dir_inode_operations = {
+       .create = rbce_create,
+       .lookup = simple_lookup,
+       .link = rbce_link,
+       .unlink = rbce_unlink,
+       .symlink = rbce_symlink,
+       .mkdir = rbce_mkdir,
+       .rmdir = rbce_rmdir,
+       .mknod = rbce_mknod,
+       .rename = rbce_rename,
+       .getattr = simple_getattr,
+};
+
+struct rbce_eng_callback rbce_rcfs_ecbs = {
+       rbce_mkdir,
+       rbce_rmdir,
+       rbce_create_config,
+       rbce_clear_config
+};
Index: linux-2.6.12-rc1/kernel/ckrm/rbce/rbce_internal.h
===================================================================
--- /dev/null
+++ linux-2.6.12-rc1/kernel/ckrm/rbce/rbce_internal.h
@@ -0,0 +1,59 @@
+/*
+ * rbce internal header file.
+ *
+ * Copyright (C) Hubertus Franke, IBM Corp. 2003
+ *           (C) Chandra Seetharaman, IBM Corp. 2003
+ *           (C) Vivek Kashyap, IBM Corp. 2004
+ *
+ * Module for loading of classification policies and providing
+ * a user API for Class-based Kernel Resource Management (CKRM)
+ *
+ * Latest version, more details at http://ckrm.sf.net
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+#ifndef _RBCE_INTERNAL_H
+#define _RBCE_INTERNAL_H
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mount.h>
+#include <linux/proc_fs.h>
+#include <linux/limits.h>
+#include <linux/pid.h>
+#include <linux/sysctl.h>
+
+#include <linux/ckrm_rc.h>
+#include <linux/ckrm_ce.h>
+#include <linux/ckrm_net.h>
+#include <linux/rbce.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+extern int rbce_enabled;
+extern struct rbce_eng_callback rbce_rcfs_ecbs;
+
+extern int rbce_mkdir(struct inode *, struct dentry *, int);
+extern int rbce_rmdir(struct inode *, struct dentry *);
+extern int rbce_create_config(void);
+extern int rbce_clear_config(void);
+
+extern void rbce_get_rule(const char *, char *);
+extern int rbce_rule_exists(const char *);
+extern int rbce_change_rule(const char *, char *);
+extern int rbce_delete_rule(const char *);
+extern int rbce_set_tasktag(int, char *);
+extern int rbce_rename_rule(const char *, const char *);
+
+#endif /* _RBCE_INTERNAL_H */
Index: linux-2.6.12-rc1/kernel/ckrm/rbce/rbce_main.c
===================================================================
--- /dev/null
+++ linux-2.6.12-rc1/kernel/ckrm/rbce/rbce_main.c
@@ -0,0 +1,97 @@
+/*
+ * Rule Functionality and module initialization and destrution
+ * for Rule-based Classification Engine (RBCE)
+ *
+ * Copyright (C) Hubertus Franke, IBM Corp. 2003
+ *           (C) Chandra Seetharaman, IBM Corp. 2003
+ *           (C) Vivek Kashyap, IBM Corp. 2004
+ *
+ * Module for loading of classification policies and providing
+ * a user API for Class-based Kernel Resource Management (CKRM)
+ *
+ * Latest version, more details at http://ckrm.sf.net
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#include "rbce_internal.h"
+
+MODULE_DESCRIPTION(RBCE_MOD_DESCR);
+MODULE_AUTHOR("Hubertus Franke, Chandra Seetharaman (IBM)");
+MODULE_LICENSE("GPL");
+
+static char modname[] = RBCE_MOD_NAME;
+
+/* Stub routines for now */
+void rbce_get_rule(const char *a, char *b)
+{
+}
+int rbce_rule_exists(const char *a)
+{
+       return 0;
+}
+int rbce_change_rule(const char *a, char *b)
+{
+       return 1;
+}
+int rbce_delete_rule(const char *a)
+{
+       return 1;
+}
+int rbce_set_tasktag(int i, char *a)
+{
+       return 1;
+}
+int rbce_rename_rule(const char *a, const char *b)
+{
+       return 1;
+}
+
+int rbce_enabled = 1;
+/* ======================= Module definition Functions ====================== 
*/
+
+int init_rbce(void)
+{
+       int rc, line;
+
+       printk(KERN_INFO "Installing \'%s\' module\n", modname);
+
+       rc = rcfs_register_engine(&rbce_rcfs_ecbs);
+       line = __LINE__;
+       if (rc)
+               goto out;
+
+       if (rcfs_mounted) {
+               rc = rbce_create_config();
+               line = __LINE__;
+               if (!rc)
+                       goto out;
+       }
+
+       rcfs_unregister_engine(&rbce_rcfs_ecbs);
+out:
+       printk(KERN_ERR "%s: error installing rc=%d line=%d\n",
+               __FUNCTION__, rc, line);
+       return rc;
+}
+
+void exit_rbce(void)
+{
+       printk(KERN_INFO "Removing \'%s\' module\n", modname);
+
+       if (rcfs_mounted)
+               rbce_clear_config();
+
+       rcfs_unregister_engine(&rbce_rcfs_ecbs);
+}
+
+module_init(init_rbce);
+module_exit(exit_rbce);

Reply via email to