snapfs.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <auth.h>
  5. #include <fcall.h>
  6. #include <thread.h>
  7. #include <9p.h>
  8. #include "snap.h"
  9. typedef struct PD PD;
  10. struct PD {
  11. int isproc;
  12. union {
  13. Proc *p;
  14. Data *d;
  15. };
  16. };
  17. PD*
  18. PDProc(Proc *p)
  19. {
  20. PD *pd;
  21. pd = emalloc(sizeof(*pd));
  22. pd->isproc = 1;
  23. pd->p = p;
  24. return pd;
  25. }
  26. PD*
  27. PDData(Data *d)
  28. {
  29. PD *pd;
  30. pd = emalloc(sizeof(*pd));
  31. pd->isproc = 0;
  32. pd->d = d;
  33. return pd;
  34. }
  35. void
  36. usage(void)
  37. {
  38. fprint(2, "usage: snapfs [-a] [-m mtpt] file\n");
  39. exits("usage");
  40. }
  41. char*
  42. memread(Proc *p, File *f, void *buf, long *count, vlong offset)
  43. {
  44. Page *pg;
  45. int po;
  46. po = offset%Pagesize;
  47. if(!(pg = findpage(p, p->pid, f->name[0], offset-po)))
  48. return "address not mapped";
  49. if(*count > Pagesize-po)
  50. *count = Pagesize-po;
  51. memmove(buf, pg->data+po, *count);
  52. return nil;
  53. }
  54. char*
  55. dataread(Data *d, void *buf, long *count, vlong offset)
  56. {
  57. assert(d != nil);
  58. if(offset >= d->len) {
  59. *count = 0;
  60. return nil;
  61. }
  62. if(offset+*count >= d->len)
  63. *count = d->len - offset;
  64. memmove(buf, d->data+offset, *count);
  65. return nil;
  66. }
  67. void
  68. fsread(Req *r)
  69. {
  70. char *e;
  71. PD *pd;
  72. Fid *fid;
  73. void *data;
  74. vlong offset;
  75. long count;
  76. fid = r->fid;
  77. data = r->ofcall.data;
  78. offset = r->ifcall.offset;
  79. count = r->ifcall.count;
  80. pd = fid->file->aux;
  81. if(pd->isproc)
  82. e = memread(pd->p, fid->file, data, &count, offset);
  83. else
  84. e = dataread(pd->d, data, &count, offset);
  85. if(e == nil)
  86. r->ofcall.count = count;
  87. respond(r, e);
  88. }
  89. Srv fs = {
  90. .read = fsread,
  91. };
  92. File*
  93. ecreatefile(File *a, char *b, char *c, ulong d, void *e)
  94. {
  95. File *f;
  96. f = createfile(a, b, c, d, e);
  97. if(f == nil)
  98. sysfatal("error creating snap tree: %r");
  99. return f;
  100. }
  101. void
  102. main(int argc, char **argv)
  103. {
  104. Biobuf *b;
  105. Data *d;
  106. File *fdir, *f;
  107. Proc *p, *plist;
  108. Tree *tree;
  109. char *mtpt, buf[32];
  110. int i, mflag;
  111. mtpt = "/proc";
  112. mflag = MBEFORE;
  113. ARGBEGIN{
  114. case 'D':
  115. chatty9p++;
  116. break;
  117. case 'd':
  118. debug = 1;
  119. break;
  120. case 'a':
  121. mflag = MAFTER;
  122. break;
  123. case 'm':
  124. mtpt = ARGF();
  125. break;
  126. default:
  127. usage();
  128. }ARGEND
  129. if(argc != 1)
  130. usage();
  131. b = Bopen(argv[0], OREAD);
  132. if(b == nil) {
  133. fprint(2, "cannot open \"%s\": %r\n", argv[0]);
  134. exits("Bopen");
  135. }
  136. if((plist = readsnap(b)) == nil) {
  137. fprint(2, "readsnap fails\n");
  138. exits("readsnap");
  139. }
  140. tree = alloctree(nil, nil, DMDIR|0555, nil);
  141. fs.tree = tree;
  142. for(p=plist; p; p=p->link) {
  143. print("process %ld %.*s\n", p->pid, 28, p->d[Pstatus] ? p->d[Pstatus]->data : "");
  144. snprint(buf, sizeof buf, "%ld", p->pid);
  145. fdir = ecreatefile(tree->root, buf, nil, DMDIR|0555, nil);
  146. ecreatefile(fdir, "ctl", nil, 0777, nil);
  147. if(p->text)
  148. ecreatefile(fdir, "text", nil, 0777, PDProc(p));
  149. ecreatefile(fdir, "mem", nil, 0666, PDProc(p));
  150. for(i=0; i<Npfile; i++) {
  151. if(d = p->d[i]) {
  152. f = ecreatefile(fdir, pfile[i], nil, 0666, PDData(d));
  153. f->length = d->len;
  154. }
  155. }
  156. }
  157. postmountsrv(&fs, nil, mtpt, mflag);
  158. exits(0);
  159. }