export-dont-include-afsconfig-to-avoid-conflicts-20011024
[openafs.git] / src / export / export.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /*
11  * export -     EXPORT kernel extension
12  */
13
14 /* Unsafe: conflicts with _KERNEL inclusion of headers below */
15 /* #include <afs/param.h> */
16 /* #include <afsconfig.h> */
17 /* RCSID("$Header$"); */
18
19 #define _KERNEL
20 #include "sys/types.h"
21 #include "sys/user.h"
22 #include "sys/conf.h"
23 #include "sys/errno.h"
24 #include "sys/device.h"
25 #include "sys/uio.h"
26 #include "sys/pri.h"
27 #include "sys/malloc.h"
28 #include "sym.h"
29 #include "export.h"
30
31 #undef RELOC
32
33 sym_t  *toc_syms;               /* symbol table                 */
34 int     toc_nsyms;              /* # of symbols                 */
35 caddr_t toc_strs;               /* string table                 */
36 int     toc_size;               /* size of toc_syms             */
37
38 /*
39  * export       -       entry point to EXPORT kernel extension
40  *
41  * Input:
42  *      cmd     -       add/delete command
43  *      uiop    -       uio vector describing any config params
44  */
45 export(cmd, uiop)
46 struct uio *uiop; {
47         int     err, monster;
48         static once;
49
50         err     = 0;
51         monster = lockl(&kernel_lock, LOCK_SHORT);
52
53         switch (cmd) {
54             case CFG_INIT:                      /* add EXPORT           */
55                 if (err = config(uiop))
56                         export_cleanup();
57                 break;
58
59             case CFG_TERM:                      /* remove EXPORT        */
60                 if (err = export_cleanup())
61                         break;
62                 break;
63
64             default:
65                 err = EINVAL;
66                 break;
67         }
68
69         if (monster != LOCK_NEST)
70                 unlockl(&kernel_lock);
71
72         return err;
73 }
74 \f
75 /*
76  * config -     process configuration data
77  */
78 config(uiop)
79 register struct uio *uiop; {
80         struct k_conf conf;
81         register struct export_nl *np;
82         register sym_t *sym;
83         register err;
84
85         if (err = uiomove((char *)&conf, sizeof (conf), UIO_WRITE, uiop))
86                 return err;
87
88         toc_nsyms = conf.nsyms;
89         toc_size  = conf.symt_sz + conf.str_sz;
90
91         if (toc_nsyms * sizeof (sym_t) != conf.symt_sz
92             || toc_size > (1024 * 1024))
93                 return EINVAL;
94
95         toc_syms = (sym_t *) xmalloc(toc_size, 2, kernel_heap);
96
97         if (!toc_syms)
98                 return ENOMEM;
99
100         toc_strs = (char *) &toc_syms[toc_nsyms];
101
102         /*
103          * copy in the symbol table and the string table
104          */
105         if (err = copyin(conf.symtab, toc_syms, conf.symt_sz)
106             || (err = copyin(conf.strtab, toc_strs, conf.str_sz))) {
107                 xmfree(toc_syms, kernel_heap);
108                 toc_syms = 0;
109                 return err;
110         }
111
112         /*
113          * `TOC' format in kernel has offsets relocated to point directly
114          * into the string table.
115          */
116         for (sym = toc_syms; sym < &toc_syms[toc_nsyms]; ++sym)
117                 if (sym->n_zeroes == 0)
118                         sym->n_nptr = sym->n_offset + toc_strs;
119
120         return 0;
121 }
122
123 /*
124  * export_cleanup -     cleanup EXPORT prior to removing kernel extension
125  */
126 export_cleanup() {
127
128         /*
129          * get rid of the symbol table
130          */
131         if (toc_syms) {
132                 xmfree(toc_syms, kernel_heap);
133                 toc_syms = 0;
134                 toc_size = 0;
135                 toc_strs = 0;
136         }
137
138         return 0;
139 }
140
141 /*
142  * import_kfunc -       import a kernel function that was mistakenly left
143  *                      off the exports list
144  *
145  * NOTE:
146  *      We are assuming that the functions we are importing from the
147  *      kernel really are within the kernel.  If they are actually
148  *      exported from some other kernel extension (but referenced in
149  *      the /unix symbol table) we are in trouble.
150  */
151 import_kfunc(struct k_func *kfp) {
152         register sym_t *sym;
153         register caddr_t *toc;
154         register i, pri;
155         static u_int *g_toc;
156
157         if (!g_toc) {
158                 sym = sym_lookup("g_toc", 0);
159                 if (!sym) {
160                         printf("\nimport: can't ascertain kernel's TOC\n");
161                         return EINVAL;
162                 }
163                 g_toc = (u_int *) sym->n_value;
164         }
165
166         sym = sym_lookup(kfp->name, 0);
167         if (!sym) {
168                 printf("\nimport: function `%s' not found\n", kfp->name);
169                 return EINVAL;
170         }
171
172         kfp->fdesc[0] = sym->n_value;
173         kfp->fdesc[1] = *g_toc;
174         kfp->fdesc[2] = 0;
175
176         *(u_int **) kfp->fpp = kfp->fdesc;
177
178         return 0;
179 }
180
181 /*
182  * import_kvar -        import a kernel variable that was mistakenly left
183  *                      off the exports list
184  */
185 import_kvar(struct k_var *kvp, caddr_t *toc) {
186         register sym_t *sym;
187         register i, pri;
188         label_t jmpbuf;
189
190         switch (setjmpx(&jmpbuf)) {
191             case 0:
192                 break;
193
194             default:
195                 return EINVAL;
196         }
197
198         sym = sym_lookup(kvp->name, 0);
199         if (!sym) {
200                 printf("\nimport: variable `%s' not found\n", kvp->name);
201                 longjmpx(EINVAL);
202         }
203
204         /*
205          * look through the caller's TOC for the reference to his surrogate
206          * variable.
207          */
208         while (*toc != kvp->varp)
209                 ++toc;
210
211         printf("import(%s): replacing my TOC at 0x%x: 0x%8x with 0x%8x\n"
212                , kvp->name, toc, *toc, sym->n_value);
213
214         /*
215          * replace reference to surrogate with reference real
216          */
217         pri = i_disable(INTMAX);
218         *toc = (caddr_t) sym->n_value;
219         i_enable(pri);
220
221         clrjmpx(&jmpbuf);
222
223         return 0;
224 }
225
226
227 /*
228  * Call vanilla syscalls
229  */
230 osetgroups(ngroups, gidset)
231     int ngroups;
232     gid_t *gidset;
233 {
234     int error;
235
236     error = setgroups(ngroups, gidset);
237     return (error);
238 }
239
240
241 okioctl(fdes, cmd, arg, ext)
242     int fdes, cmd, arg;
243     caddr_t ext;
244 {
245     int error;
246     
247     error = kioctl(fdes, cmd, arg, ext);
248     return (error);
249 }
250
251 #ifdef  notdef
252 ocore(signo, sigctx)
253     char signo;
254     struct sigcontext *sigctx;
255 {
256     int error;
257 #include <sys/user.h>
258     u.u_sigflags[signo] |= SA_FULLDUMP;         /* XXX */
259     error = core(signo, sigctx);
260     return (error);
261 }
262 #endif
263