On 8/4/06, Matt Helsley <[EMAIL PROTECTED]> wrote: > > Since the interface looks less elegant than mkdir I think you need to > support your assertion. No offense but until we see the code I don't > think we can really see that it's any simpler. >
Here's the code for the /proc manipulation part - 133 lines for all the filesystem issues, with no reliance on configfs or sysfs. (Although I guess it could possibly go in sysfs rather than procfs). Each class directory that's created has a set of operation files created in it, such as ".create", ".delete", ".enter", ".status", etc. Reading or writing on these causes the appropriate callback functions to be called. The actual operation callbacks themselves don't have much in the way of filesystem support in them. E.g. container_op_create() just calls create_proc_entry() to create the main directory for the resource group, and then init_container_dir() to create one entry for each control file. Liveness/refcounting issues between the procfs interface and the internal objects are handled by having the proc_dir_entry just contain an id, and having the open() method look up the id in a table of live containers, and return one with a refcount held if it's found. Granted, this is simpler than CKRM in that it doesn't have the modular resource controller support in it, but that wouldn't take much effort to add. Paul static container_op ops[] = { { {}, ".enter", container_op_enter }, { {}, ".root", container_op_root }, { {}, ".kill", container_op_kill }, { {}, ".create", container_op_create }, { {}, ".delete", container_op_delete }, { {}, ".inode", container_op_inode }, { {}, ".status", NULL, container_task_show }, { {}, ".sockets", NULL, container_sockets_show }, { {}, ".dirtylimit", container_op_dirtylimit }, }; static int container_proc_open(struct inode *inode, struct file *file) { int ret; int (*showfn)(struct seq_file *, void *); struct proc_dir_entry *pde = PDE(inode); container *container; container_op *op = (container_op*) file->f_op; container_get_by_id((u32)(long)pde->data, &container); if (!container) return -ESRCH; if (op->showfn) { showfn = op->showfn; } else { showfn = container_empty_show; } ret = single_open(file, showfn, container); if (ret) { put_container(&container, "bad open", "", NULL); } return ret; } static ssize_t container_proc_write(struct file *file, const char *ubuf, size_t count, loff_t *off) { container_op *op = (container_op *) file->f_op; struct seq_file *m = (struct seq_file *)file->private_data; container *g = m->private; int ret; #define MAX_CMD 128 int len = count; char kbuf[MAX_CMD]; if (len >= MAX_CMD) return -EINVAL; if (len > 0) { if (copy_from_user(kbuf, ubuf, len)) return -EFAULT; if (kbuf[len - 1] == '\n') len --; } kbuf[len] = 0; ret = op->writefn(g, kbuf); if (!ret) ret = count; return ret; } static int container_proc_release(struct inode *inode, struct file *file) { struct seq_file *m = (struct seq_file *)file->private_data; put_container((container **)&m->private, "proc_release", "", NULL); return seq_release(inode, file); } static struct file_operations container_proc_fops_template = { open: container_proc_open, read: seq_read, write: container_proc_write, llseek: seq_lseek, release: container_proc_release, }; static void zap_container_dir(struct proc_dir_entry *dir) { int i; for (i = 0; i < sizeof(ops) / sizeof(container_op); i++) { container_op *op = &ops[i]; remove_proc_entry(op->name, dir); } } static int init_container_dir(struct proc_dir_entry *dir, container *g) { int i; for (i = 0; i < sizeof(ops) / sizeof(container_op); i++) { int mode = 0; struct proc_dir_entry *pde; container_op *op = &ops[i]; if (op->showfn) mode |= 0400; if (op->writefn) mode |= 0200; pde = create_proc_entry(op->name, mode | S_IFREG, dir); if (!pde) { printk(KERN_ERR "Error creating %s for container %s\n", op->name, g->name); zap_container_dir(dir); return -EIO; } pde->data = (void *)(long)g->id; pde->proc_fops = &op->fops; } return 0; } static int __init init_container(void) { int ret, i; container_cache = kmem_cache_create("container_cache", sizeof(container), 0, SLAB_PANIC, NULL, NULL); for (i = 0; i < sizeof(ops) / sizeof(container_op); i++) { container_op *op = &ops[i]; memcpy(&op->fops, &container_proc_fops_template, sizeof(op->fops)); } ret = container_op_create(NULL, "container"); if (ret) printk(KERN_ERR "Container init failed!\n"); return ret; } module_init(init_container); ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys -- and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ ckrm-tech mailing list https://lists.sourceforge.net/lists/listinfo/ckrm-tech