2 * linux/kernel/vserver/proc.c
4 * Virtual Context Support
6 * Copyright (C) 2003-2007 Herbert Pƶtzl
8 * V0.01 basic structure
9 * V0.02 adaptation vs1.3.0
10 * V0.03 proc permissions
11 * V0.04 locking/generic
12 * V0.05 next generation procfs
13 * V0.06 inode validation
14 * V0.07 generic rewrite vid
15 * V0.08 remove inode type
19 #include <linux/errno.h>
20 #include <linux/proc_fs.h>
21 #include <linux/sched.h>
22 #include <linux/vs_context.h>
23 #include <linux/vs_network.h>
24 #include <linux/vs_cvirt.h>
26 #include <linux/vserver/switch.h>
27 #include <linux/vserver/global.h>
29 #include <asm/uaccess.h>
30 #include <asm/unistd.h>
32 #include "cvirt_proc.h"
33 #include "cacct_proc.h"
34 #include "limit_proc.h"
35 #include "sched_proc.h"
36 #include "vci_config.h"
38 static struct proc_dir_entry *proc_virtual;
40 static struct proc_dir_entry *proc_virtnet;
43 /* first the actual feeds */
46 static int proc_vci(char *buffer)
48 return sprintf(buffer,
49 "VCIVersion:\t%04x:%04x\n"
59 static int proc_virtual_info(char *buffer)
61 return proc_vci(buffer);
64 static int proc_virtual_status(char *buffer)
66 return sprintf(buffer,
69 "#NSProxy:\t%d\t%d %d %d %d\n"
70 ,atomic_read(&vx_global_ctotal)
71 ,atomic_read(&vx_global_cactive)
72 ,atomic_read(&vs_global_nsproxy)
73 ,atomic_read(&vs_global_fs)
74 ,atomic_read(&vs_global_mnt_ns)
75 ,atomic_read(&vs_global_uts_ns)
76 ,atomic_read(&vs_global_ipc_ns)
81 int proc_vxi_info (struct vx_info *vxi, char *buffer)
85 length = sprintf(buffer,
96 int proc_vxi_status (struct vx_info *vxi, char *buffer)
100 length = sprintf(buffer,
107 ,atomic_read(&vxi->vx_usecnt)
108 ,atomic_read(&vxi->vx_tasks)
109 ,(unsigned long long)vxi->vx_flags
110 ,(unsigned long long)vxi->vx_bcaps
111 ,(unsigned long long)vxi->vx_ccaps
117 int proc_vxi_limit (struct vx_info *vxi, char *buffer)
119 return vx_info_proc_limit(&vxi->limit, buffer);
122 int proc_vxi_sched (struct vx_info *vxi, char *buffer)
126 length = vx_info_proc_sched(&vxi->sched, buffer);
127 for_each_online_cpu(cpu) {
128 length += vx_info_proc_sched_pc(
129 &vx_per_cpu(vxi, sched_pc, cpu),
130 buffer + length, cpu);
135 int proc_vxi_nsproxy (struct vx_info *vxi, char *buffer)
137 return vx_info_proc_nsproxy(vxi->vx_nsproxy, buffer);
140 int proc_vxi_cvirt (struct vx_info *vxi, char *buffer)
145 length = vx_info_proc_cvirt(&vxi->cvirt, buffer);
146 for_each_online_cpu(cpu) {
147 length += vx_info_proc_cvirt_pc(
148 &vx_per_cpu(vxi, cvirt_pc, cpu),
149 buffer + length, cpu);
154 int proc_vxi_cacct (struct vx_info *vxi, char *buffer)
156 return vx_info_proc_cacct(&vxi->cacct, buffer);
160 static int proc_virtnet_info(char *buffer)
162 return proc_vci(buffer);
165 static int proc_virtnet_status(char *buffer)
167 return sprintf(buffer,
170 ,atomic_read(&nx_global_ctotal)
171 ,atomic_read(&nx_global_cactive)
175 int proc_nxi_info (struct nx_info *nxi, char *buffer)
179 length = sprintf(buffer,
185 for (i=0; i<nxi->nbipv4; i++) {
186 length += sprintf(buffer + length,
187 "%d:\t" NIPQUAD_FMT "/" NIPQUAD_FMT "\n", i,
188 NIPQUAD(nxi->ipv4[i]), NIPQUAD(nxi->mask[i]));
193 int proc_nxi_status (struct nx_info *nxi, char *buffer)
197 length = sprintf(buffer,
202 ,atomic_read(&nxi->nx_usecnt)
203 ,atomic_read(&nxi->nx_tasks)
204 ,(unsigned long long)nxi->nx_flags
205 ,(unsigned long long)nxi->nx_ncaps
212 /* here the inode helpers */
218 struct inode_operations *iop;
219 struct file_operations *fop;
223 static struct inode *vs_proc_make_inode(struct super_block *sb, struct vs_entry *p)
225 struct inode *inode = new_inode(sb);
230 inode->i_mode = p->mode;
232 inode->i_op = p->iop;
234 inode->i_fop = p->fop;
236 inode->i_nlink = (p->mode & S_IFDIR) ? 2 : 1;
237 inode->i_flags |= S_IMMUTABLE;
239 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
248 static struct dentry *vs_proc_instantiate(struct inode *dir,
249 struct dentry *dentry, int id, void *ptr)
251 struct vs_entry *p = ptr;
252 struct inode *inode = vs_proc_make_inode(dir->i_sb, p);
253 struct dentry *error = ERR_PTR(-EINVAL);
258 PROC_I(inode)->op = p->op;
259 PROC_I(inode)->fd = id;
260 d_add(dentry, inode);
268 typedef struct dentry *instantiate_t(struct inode *, struct dentry *, int, void *);
271 * Fill a directory entry.
273 * If possible create the dcache entry and derive our inode number and
274 * file type from dcache entry.
276 * Since all of the proc inode numbers are dynamically generated, the inode
277 * numbers do not exist until the inode is cache. This means creating the
278 * the dcache entry in readdir is necessary to keep the inode numbers
279 * reported by readdir in sync with the inode numbers reported
282 static int proc_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
283 char *name, int len, instantiate_t instantiate, int id, void *ptr)
285 struct dentry *child, *dir = filp->f_dentry;
289 unsigned type = DT_UNKNOWN;
293 qname.hash = full_name_hash(name, len);
295 child = d_lookup(dir, &qname);
298 new = d_alloc(dir, &qname);
300 child = instantiate(dir->d_inode, new, id, ptr);
307 if (!child || IS_ERR(child) || !child->d_inode)
308 goto end_instantiate;
309 inode = child->d_inode;
312 type = inode->i_mode >> 12;
317 ino = find_inode_number(dir, &qname);
320 return filldir(dirent, name, len, filp->f_pos, ino, type);
325 /* get and revalidate vx_info/xid */
328 struct vx_info *get_proc_vx_info(struct inode *inode)
330 return lookup_vx_info(PROC_I(inode)->fd);
333 static int proc_xid_revalidate(struct dentry * dentry, struct nameidata *nd)
335 struct inode *inode = dentry->d_inode;
336 xid_t xid = PROC_I(inode)->fd;
338 if (!xid || xid_is_hashed(xid))
345 /* get and revalidate nx_info/nid */
347 static int proc_nid_revalidate(struct dentry * dentry, struct nameidata *nd)
349 struct inode *inode = dentry->d_inode;
350 nid_t nid = PROC_I(inode)->fd;
352 if (!nid || nid_is_hashed(nid))
360 #define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
362 static ssize_t proc_vs_info_read(struct file * file, char __user * buf,
363 size_t count, loff_t *ppos)
365 struct inode *inode = file->f_dentry->d_inode;
369 if (count > PROC_BLOCK_SIZE)
370 count = PROC_BLOCK_SIZE;
372 /* fade that out as soon as stable */
373 WARN_ON(PROC_I(inode)->fd);
375 if (!(page = __get_free_page(GFP_KERNEL)))
378 BUG_ON(!PROC_I(inode)->op.proc_vs_read);
379 length = PROC_I(inode)->op.proc_vs_read((char*)page);
382 length = simple_read_from_buffer(buf, count, ppos,
383 (char *)page, length);
389 static ssize_t proc_vx_info_read(struct file * file, char __user * buf,
390 size_t count, loff_t *ppos)
392 struct inode *inode = file->f_dentry->d_inode;
393 struct vx_info *vxi = NULL;
394 xid_t xid = PROC_I(inode)->fd;
398 if (count > PROC_BLOCK_SIZE)
399 count = PROC_BLOCK_SIZE;
401 /* fade that out as soon as stable */
403 vxi = lookup_vx_info(xid);
408 if (!(page = __get_free_page(GFP_KERNEL)))
411 BUG_ON(!PROC_I(inode)->op.proc_vxi_read);
412 length = PROC_I(inode)->op.proc_vxi_read(vxi, (char*)page);
415 length = simple_read_from_buffer(buf, count, ppos,
416 (char *)page, length);
425 static ssize_t proc_nx_info_read(struct file * file, char __user * buf,
426 size_t count, loff_t *ppos)
428 struct inode *inode = file->f_dentry->d_inode;
429 struct nx_info *nxi = NULL;
430 nid_t nid = PROC_I(inode)->fd;
434 if (count > PROC_BLOCK_SIZE)
435 count = PROC_BLOCK_SIZE;
437 /* fade that out as soon as stable */
439 nxi = lookup_nx_info(nid);
444 if (!(page = __get_free_page(GFP_KERNEL)))
447 BUG_ON(!PROC_I(inode)->op.proc_nxi_read);
448 length = PROC_I(inode)->op.proc_nxi_read(nxi, (char*)page);
451 length = simple_read_from_buffer(buf, count, ppos,
452 (char *)page, length);
463 /* here comes the lower level */
466 #define NOD(NAME, MODE, IOP, FOP, OP) { \
467 .len = sizeof(NAME) - 1, \
476 #define DIR(NAME, MODE, OTYPE) \
477 NOD(NAME, (S_IFDIR|(MODE)), \
478 &proc_##OTYPE##_inode_operations, \
479 &proc_##OTYPE##_file_operations, { } )
481 #define INF(NAME, MODE, OTYPE) \
482 NOD(NAME, (S_IFREG|(MODE)), NULL, \
483 &proc_vs_info_file_operations, \
484 { .proc_vs_read = &proc_##OTYPE } )
486 #define VINF(NAME, MODE, OTYPE) \
487 NOD(NAME, (S_IFREG|(MODE)), NULL, \
488 &proc_vx_info_file_operations, \
489 { .proc_vxi_read = &proc_##OTYPE } )
491 #define NINF(NAME, MODE, OTYPE) \
492 NOD(NAME, (S_IFREG|(MODE)), NULL, \
493 &proc_nx_info_file_operations, \
494 { .proc_nxi_read = &proc_##OTYPE } )
497 static struct file_operations proc_vs_info_file_operations = {
498 .read = proc_vs_info_read,
501 static struct file_operations proc_vx_info_file_operations = {
502 .read = proc_vx_info_read,
505 static struct dentry_operations proc_xid_dentry_operations = {
506 .d_revalidate = proc_xid_revalidate,
509 static struct vs_entry vx_base_stuff[] = {
510 VINF("info", S_IRUGO, vxi_info),
511 VINF("status", S_IRUGO, vxi_status),
512 VINF("limit", S_IRUGO, vxi_limit),
513 VINF("sched", S_IRUGO, vxi_sched),
514 VINF("nsproxy", S_IRUGO, vxi_nsproxy),
515 VINF("cvirt", S_IRUGO, vxi_cvirt),
516 VINF("cacct", S_IRUGO, vxi_cacct),
523 static struct dentry *proc_xid_instantiate(struct inode *dir,
524 struct dentry *dentry, int id, void *ptr)
526 dentry->d_op = &proc_xid_dentry_operations;
527 return vs_proc_instantiate(dir, dentry, id, ptr);
530 static struct dentry *proc_xid_lookup(struct inode *dir,
531 struct dentry *dentry, struct nameidata *nd)
533 struct vs_entry *p = vx_base_stuff;
534 struct dentry *error = ERR_PTR(-ENOENT);
536 for (; p->name; p++) {
537 if (p->len != dentry->d_name.len)
539 if (!memcmp(dentry->d_name.name, p->name, p->len))
545 error = proc_xid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
550 static int proc_xid_readdir(struct file * filp,
551 void * dirent, filldir_t filldir)
553 struct dentry *dentry = filp->f_dentry;
554 struct inode *inode = dentry->d_inode;
555 struct vs_entry *p = vx_base_stuff;
556 int size = sizeof(vx_base_stuff)/sizeof(struct vs_entry);
564 if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
569 ino = parent_ino(dentry);
570 if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
578 for (p += index; p->name; p++) {
579 if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
580 vs_proc_instantiate, PROC_I(inode)->fd, p))
592 static struct file_operations proc_nx_info_file_operations = {
593 .read = proc_nx_info_read,
596 static struct dentry_operations proc_nid_dentry_operations = {
597 .d_revalidate = proc_nid_revalidate,
600 static struct vs_entry nx_base_stuff[] = {
601 NINF("info", S_IRUGO, nxi_info),
602 NINF("status", S_IRUGO, nxi_status),
607 static struct dentry *proc_nid_instantiate(struct inode *dir,
608 struct dentry *dentry, int id, void *ptr)
610 dentry->d_op = &proc_nid_dentry_operations;
611 return vs_proc_instantiate(dir, dentry, id, ptr);
614 static struct dentry *proc_nid_lookup(struct inode *dir,
615 struct dentry *dentry, struct nameidata *nd)
617 struct vs_entry *p = nx_base_stuff;
618 struct dentry *error = ERR_PTR(-ENOENT);
620 for (; p->name; p++) {
621 if (p->len != dentry->d_name.len)
623 if (!memcmp(dentry->d_name.name, p->name, p->len))
629 error = proc_nid_instantiate(dir, dentry, PROC_I(dir)->fd, p);
634 static int proc_nid_readdir(struct file * filp,
635 void * dirent, filldir_t filldir)
637 struct dentry *dentry = filp->f_dentry;
638 struct inode *inode = dentry->d_inode;
639 struct vs_entry *p = nx_base_stuff;
640 int size = sizeof(nx_base_stuff)/sizeof(struct vs_entry);
648 if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
653 ino = parent_ino(dentry);
654 if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
662 for (p += index; p->name; p++) {
663 if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
664 vs_proc_instantiate, PROC_I(inode)->fd, p))
675 #define MAX_MULBY10 ((~0U-9)/10)
677 static inline int atovid(const char *str, int len)
687 if (vid >= MAX_MULBY10)
697 /* now the upper level (virtual) */
700 static struct file_operations proc_xid_file_operations = {
701 .read = generic_read_dir,
702 .readdir = proc_xid_readdir,
705 static struct inode_operations proc_xid_inode_operations = {
706 .lookup = proc_xid_lookup,
709 static struct vs_entry vx_virtual_stuff[] = {
710 INF("info", S_IRUGO, virtual_info),
711 INF("status", S_IRUGO, virtual_status),
712 DIR(NULL, S_IRUGO|S_IXUGO, xid),
716 static struct dentry *proc_virtual_lookup(struct inode *dir,
717 struct dentry *dentry, struct nameidata *nd)
719 struct vs_entry *p = vx_virtual_stuff;
720 struct dentry *error = ERR_PTR(-ENOENT);
723 for (; p->name; p++) {
724 if (p->len != dentry->d_name.len)
726 if (!memcmp(dentry->d_name.name, p->name, p->len))
732 id = atovid(dentry->d_name.name, dentry->d_name.len);
733 if ((id < 0) || !xid_is_hashed(id))
737 error = proc_xid_instantiate(dir, dentry, id, p);
742 static struct file_operations proc_nid_file_operations = {
743 .read = generic_read_dir,
744 .readdir = proc_nid_readdir,
747 static struct inode_operations proc_nid_inode_operations = {
748 .lookup = proc_nid_lookup,
751 static struct vs_entry nx_virtnet_stuff[] = {
752 INF("info", S_IRUGO, virtnet_info),
753 INF("status", S_IRUGO, virtnet_status),
754 DIR(NULL, S_IRUGO|S_IXUGO, nid),
758 static struct dentry *proc_virtnet_lookup(struct inode *dir,
759 struct dentry *dentry, struct nameidata *nd)
761 struct vs_entry *p = nx_virtnet_stuff;
762 struct dentry *error = ERR_PTR(-ENOENT);
765 for (; p->name; p++) {
766 if (p->len != dentry->d_name.len)
768 if (!memcmp(dentry->d_name.name, p->name, p->len))
774 id = atovid(dentry->d_name.name, dentry->d_name.len);
775 if ((id < 0) || !nid_is_hashed(id))
779 error = proc_nid_instantiate(dir, dentry, id, p);
786 #define PROC_NUMBUF 10
787 #define PROC_MAXVIDS 32
789 int proc_virtual_readdir(struct file * filp,
790 void * dirent, filldir_t filldir)
792 struct dentry *dentry = filp->f_dentry;
793 struct inode *inode = dentry->d_inode;
794 struct vs_entry *p = vx_virtual_stuff;
795 int size = sizeof(vx_virtual_stuff)/sizeof(struct vs_entry);
797 unsigned int xid_array[PROC_MAXVIDS];
798 char buf[PROC_NUMBUF];
799 unsigned int nr_xids, i;
806 if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
811 ino = parent_ino(dentry);
812 if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
820 for (p += index; p->name; p++) {
821 if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
822 vs_proc_instantiate, 0, p))
828 p = &vx_virtual_stuff[size-1];
829 nr_xids = get_xid_list(index, xid_array, PROC_MAXVIDS);
830 for (i = 0; i < nr_xids; i++) {
831 int n, xid = xid_array[i];
832 unsigned int j = PROC_NUMBUF;
835 do buf[--j] = '0' + (n % 10); while (n /= 10);
837 if (proc_fill_cache(filp, dirent, filldir, buf+j, PROC_NUMBUF-j,
838 vs_proc_instantiate, xid, p))
848 static int proc_virtual_getattr(struct vfsmount *mnt,
849 struct dentry *dentry, struct kstat *stat)
851 struct inode *inode = dentry->d_inode;
853 generic_fillattr(inode, stat);
854 stat->nlink = 2 + atomic_read(&vx_global_cactive);
858 static struct file_operations proc_virtual_dir_operations = {
859 .read = generic_read_dir,
860 .readdir = proc_virtual_readdir,
863 static struct inode_operations proc_virtual_dir_inode_operations = {
864 .getattr = proc_virtual_getattr,
865 .lookup = proc_virtual_lookup,
872 int proc_virtnet_readdir(struct file * filp,
873 void * dirent, filldir_t filldir)
875 struct dentry *dentry = filp->f_dentry;
876 struct inode *inode = dentry->d_inode;
877 struct vs_entry *p = nx_virtnet_stuff;
878 int size = sizeof(nx_virtnet_stuff)/sizeof(struct vs_entry);
880 unsigned int nid_array[PROC_MAXVIDS];
881 char buf[PROC_NUMBUF];
882 unsigned int nr_nids, i;
889 if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
894 ino = parent_ino(dentry);
895 if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
903 for (p += index; p->name; p++) {
904 if (proc_fill_cache(filp, dirent, filldir, p->name, p->len,
905 vs_proc_instantiate, 0, p))
911 p = &nx_virtnet_stuff[size-1];
912 nr_nids = get_nid_list(index, nid_array, PROC_MAXVIDS);
913 for (i = 0; i < nr_nids; i++) {
914 int n, nid = nid_array[i];
915 unsigned int j = PROC_NUMBUF;
918 do buf[--j] = '0' + (n % 10); while (n /= 10);
920 if (proc_fill_cache(filp, dirent, filldir, buf+j, PROC_NUMBUF-j,
921 vs_proc_instantiate, nid, p))
931 static int proc_virtnet_getattr(struct vfsmount *mnt,
932 struct dentry *dentry, struct kstat *stat)
934 struct inode *inode = dentry->d_inode;
936 generic_fillattr(inode, stat);
937 stat->nlink = 2 + atomic_read(&nx_global_cactive);
941 static struct file_operations proc_virtnet_dir_operations = {
942 .read = generic_read_dir,
943 .readdir = proc_virtnet_readdir,
946 static struct inode_operations proc_virtnet_dir_inode_operations = {
947 .getattr = proc_virtnet_getattr,
948 .lookup = proc_virtnet_lookup,
953 void proc_vx_init(void)
955 struct proc_dir_entry *ent;
957 ent = proc_mkdir("virtual", 0);
959 ent->proc_fops = &proc_virtual_dir_operations;
960 ent->proc_iops = &proc_virtual_dir_inode_operations;
964 ent = proc_mkdir("virtnet", 0);
966 ent->proc_fops = &proc_virtnet_dir_operations;
967 ent->proc_iops = &proc_virtnet_dir_inode_operations;
978 int proc_pid_vx_info(struct task_struct *p, char *buffer)
981 char * orig = buffer;
983 buffer += sprintf (buffer,"XID:\t%d\n", vx_task_xid(p));
985 vxi = task_get_vx_info(p);
989 buffer += sprintf (buffer,"BCaps:\t%016llx\n"
990 ,(unsigned long long)vxi->vx_bcaps);
991 buffer += sprintf (buffer,"CCaps:\t%016llx\n"
992 ,(unsigned long long)vxi->vx_ccaps);
993 buffer += sprintf (buffer,"CFlags:\t%016llx\n"
994 ,(unsigned long long)vxi->vx_flags);
995 buffer += sprintf (buffer,"CIPid:\t%d\n"
1000 return buffer - orig;
1004 int proc_pid_nx_info(struct task_struct *p, char *buffer)
1006 struct nx_info *nxi;
1007 char * orig = buffer;
1010 buffer += sprintf (buffer,"NID:\t%d\n", nx_task_nid(p));
1012 nxi = task_get_nx_info(p);
1016 buffer += sprintf (buffer,"NCaps:\t%016llx\n"
1017 ,(unsigned long long)nxi->nx_ncaps);
1018 buffer += sprintf (buffer,"NFlags:\t%016llx\n"
1019 ,(unsigned long long)nxi->nx_flags);
1021 for (i=0; i<nxi->nbipv4; i++){
1022 buffer += sprintf (buffer,
1023 "V4Root[%d]:\t%d.%d.%d.%d/%d.%d.%d.%d\n", i
1024 ,NIPQUAD(nxi->ipv4[i])
1025 ,NIPQUAD(nxi->mask[i]));
1027 buffer += sprintf (buffer,
1028 "V4Root[bcast]:\t%d.%d.%d.%d\n"
1029 ,NIPQUAD(nxi->v4_bcast));
1033 return buffer - orig;