root/src/modules/lua.c

Revision a2b666a8ab8d7131bde0c3d600c5f4b8d7fa2709, 19.1 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

make modules actually be lua modules

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #include "noit_defines.h"
7
8 #include "noit_conf.h"
9 #include "noit_module.h"
10 #include "noit_check.h"
11 #include "noit_check_tools.h"
12 #include "utils/noit_log.h"
13 #include "lua_noit.h"
14
15 #include <assert.h>
16
17 static noit_log_stream_t nlerr = NULL;
18 static noit_log_stream_t nldeb = NULL;
19 static noit_hash_table noit_coros = NOIT_HASH_EMPTY;
20
21 struct loader_conf {
22   char *script_dir;
23 };
24 static struct loader_conf *__get_loader_conf(noit_module_loader_t *self) {
25   struct loader_conf *c;
26   c = noit_image_get_userdata(&self->hdr);
27   if(!c) {
28     c = calloc(1, sizeof(*c));
29     noit_image_set_userdata(&self->hdr, c);
30   }
31   return c;
32 }
33 static void
34 noit_lua_loader_set_directory(noit_module_loader_t *self, char *dir) {
35   struct loader_conf *c = __get_loader_conf(self);
36   if(c->script_dir) free(c->script_dir);
37   c->script_dir = strdup(dir);
38 }
39 static const char *
40 noit_lua_loader_get_directory(noit_module_loader_t *self) {
41   struct loader_conf *c = __get_loader_conf(self);
42   return c->script_dir;
43 }
44
45 noit_lua_check_info_t *
46 get_ci(lua_State *L) {
47   noit_lua_check_info_t *v = NULL;
48   if(noit_hash_retrieve(&noit_coros, (const char *)&L, sizeof(L), (void **)&v))
49     return v;
50   return NULL;
51 }
52
53 static void
54 noit_event_dispose(void *ev) {
55   int mask;
56   eventer_t *value = ev;
57   eventer_t e = *value;
58   if(e->fd >= 0) e->opset->close(e->fd, &mask, e);
59   if(e->mask && eventer_remove(e)) eventer_free(e);
60   if(!e->mask) eventer_free(e);
61   free(ev);
62 }
63 void
64 noit_lua_check_register_event(noit_lua_check_info_t *ci, eventer_t e) {
65   eventer_t *eptr;
66   eptr = calloc(1, sizeof(*eptr));
67   memcpy(eptr, &e, sizeof(*eptr));
68   if(!ci->events) ci->events = calloc(1, sizeof(*ci->events));
69   assert(noit_hash_store(ci->events, (const char *)eptr, sizeof(*eptr), eptr));
70 }
71 void
72 noit_lua_check_deregister_event(noit_lua_check_info_t *ci, eventer_t e,
73                                 int tofree) {
74   assert(ci->events);
75   assert(noit_hash_delete(ci->events, (const char *)&e, sizeof(e),
76                           NULL, tofree ? noit_event_dispose : free));
77 }
78 void
79 noit_lua_check_clean_events(noit_lua_check_info_t *ci) {
80   noit_hash_destroy(ci->events, NULL, noit_event_dispose);
81   free(ci->events);
82   ci->events = NULL;
83 }
84
85 static void
86 noit_lua_pushmodule(lua_State *L, const char *m) {
87   int stack_pos = LUA_GLOBALSINDEX;
88   char *copy, *part, *brkt;
89   copy = alloca(strlen(m)+1);
90   assert(copy);
91   memcpy(copy,m,strlen(m)+1);
92
93   for(part = strtok_r(copy, ".", &brkt);
94       part;
95       part = strtok_r(NULL, ".", &brkt)) {
96     lua_getfield(L, stack_pos, part);
97     if(stack_pos == -1) lua_remove(L, -2);
98     else stack_pos = -1;
99   }
100 }
101 static void
102 noit_lua_hash_to_table(lua_State *L,
103                        noit_hash_table *t) {
104   noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
105   const char *key, *value;
106   int klen;
107   lua_createtable(L, 0, t ? t->size : 0);
108   if(t) {
109     while(noit_hash_next(t, &iter, &key, &klen, (void **)&value)) {
110       lua_pushlstring(L, value, strlen(value));
111       lua_setfield(L, -2, key);
112     }
113   }
114   return;
115 }
116 static int
117 noit_module_index_func(lua_State *L) {
118   int n;
119   n = lua_gettop(L);    /* number of arguments */
120   assert(n == 2);
121   if(!luaL_checkudata(L, 1, "noit_module_t")) {
122     luaL_error(L, "metatable error, arg1 not a noit_module_t!");
123   }
124   return 0;
125 }
126 static int
127 noit_lua_set_available(lua_State *L) {
128   noit_check_t *check;
129   noit_lua_check_info_t *ci;
130   if(lua_gettop(L)) luaL_error(L, "wrong number of arguments");
131   check = lua_touserdata(L, lua_upvalueindex(1));
132   ci = check->closure;
133   ci->current.available = lua_tointeger(L, lua_upvalueindex(2));
134   return 0;
135 }
136 static int
137 noit_lua_set_state(lua_State *L) {
138   noit_check_t *check;
139   noit_lua_check_info_t *ci;
140   if(lua_gettop(L)) luaL_error(L, "wrong number of arguments");
141   check = lua_touserdata(L, lua_upvalueindex(1));
142   ci = check->closure;
143   ci->current.state = lua_tointeger(L, lua_upvalueindex(2));
144   return 0;
145 }
146 static int
147 noit_lua_set_status(lua_State *L) {
148   noit_check_t *check;
149   noit_lua_check_info_t *ci;
150   if(lua_gettop(L) != 1) luaL_error(L, "wrong number of arguments");
151   check = lua_touserdata(L, lua_upvalueindex(1));
152   ci = check->closure;
153   ci->current.status = strdup(lua_tostring(L, 1));
154   return 0;
155 }
156 static int
157 noit_lua_set_metric(lua_State *L) {
158   noit_check_t *check;
159   noit_lua_check_info_t *ci;
160   const char *metric_name;
161   metric_type_t metric_type;
162
163   double __n;
164   int32_t __i;
165   u_int32_t __I;
166   int64_t __l;
167   u_int64_t __L;
168
169   if(lua_gettop(L) != 2) luaL_error(L, "wrong number of arguments");
170   check = lua_touserdata(L, lua_upvalueindex(1));
171   ci = check->closure;
172   if(!lua_isstring(L, 1)) luaL_error(L, "argument #1 must be a string");
173   metric_name = lua_tostring(L, 1);
174   metric_type = lua_tointeger(L, lua_upvalueindex(2));
175   if(lua_isnil(L, 2)) {
176     noit_stats_set_metric(&ci->current, metric_name, metric_type, NULL);
177     return 0;
178   }
179   switch(metric_type) {
180     case METRIC_GUESS:
181     case METRIC_STRING:
182       noit_stats_set_metric(&ci->current, metric_name, metric_type,
183                             (void *)lua_tostring(L, 2));
184       break;
185     case METRIC_INT32:
186       __i = luaL_optinteger(L, 2, 0);
187       noit_stats_set_metric(&ci->current, metric_name, metric_type, &__i);
188       break;
189     case METRIC_UINT32:
190       __I = luaL_optinteger(L, 2, 0);
191       noit_stats_set_metric(&ci->current, metric_name, metric_type, &__I);
192       break;
193     case METRIC_INT64:
194       __l = luaL_optinteger(L, 2, 0);
195       noit_stats_set_metric(&ci->current, metric_name, metric_type, &__l);
196       break;
197     case METRIC_UINT64:
198       __L = luaL_optinteger(L, 2, 0);
199       noit_stats_set_metric(&ci->current, metric_name, metric_type, &__L);
200       break;
201     case METRIC_DOUBLE:
202       __n = luaL_optnumber(L, 2, 0);
203       noit_stats_set_metric(&ci->current, metric_name, metric_type, &__n);
204       break;
205   }
206   return 0;
207 }
208 static int
209 noit_check_index_func(lua_State *L) {
210   int n;
211   const char *k;
212   noit_check_t **udata, *check;
213   n = lua_gettop(L);    /* number of arguments */
214   assert(n == 2);
215   if(!luaL_checkudata(L, 1, "noit_check_t")) {
216     luaL_error(L, "metatable error, arg1 not a noit_check_t!");
217   }
218   udata = lua_touserdata(L, 1);
219   check = *udata;
220   if(!lua_isstring(L, 2)) {
221     luaL_error(L, "metatable error, arg2 not a string!");
222   }
223   k = lua_tostring(L, 2);
224   switch(*k) {
225     case 'a':
226       if(!strcmp(k, "available")) {
227         lua_pushlightuserdata(L, check);
228         lua_pushinteger(L, NP_AVAILABLE);
229         lua_pushcclosure(L, noit_lua_set_available, 2);
230       }
231       else break;
232       return 1;
233     case 'b':
234       if(!strcmp(k, "bad")) {
235         lua_pushlightuserdata(L, check);
236         lua_pushinteger(L, NP_BAD);
237         lua_pushcclosure(L, noit_lua_set_state, 2);
238       }
239       else break;
240       return 1;
241     case 'c':
242       if(!strcmp(k, "config")) noit_lua_hash_to_table(L, check->config);
243       else break;
244       return 1;
245     case 'g':
246       if(!strcmp(k, "good")) {
247         lua_pushlightuserdata(L, check);
248         lua_pushinteger(L, NP_GOOD);
249         lua_pushcclosure(L, noit_lua_set_state, 2);
250       }
251       else break;
252       return 1;
253     case 'm':
254       if(!strcmp(k, "module")) lua_pushstring(L, check->module);
255
256 #define IF_METRIC_BLOCK(name,type) \
257       if(!strcmp(k, name)) { \
258         lua_pushlightuserdata(L, check); \
259         lua_pushinteger(L, type); \
260         lua_pushcclosure(L, noit_lua_set_metric, 2); \
261       }
262
263       else IF_METRIC_BLOCK("metric", METRIC_GUESS)
264       else IF_METRIC_BLOCK("metric_string", METRIC_STRING)
265       else IF_METRIC_BLOCK("metric_int32", METRIC_INT32)
266       else IF_METRIC_BLOCK("metric_uint32", METRIC_UINT32)
267       else IF_METRIC_BLOCK("metric_int64", METRIC_INT64)
268       else IF_METRIC_BLOCK("metric_uint64", METRIC_UINT64)
269       else IF_METRIC_BLOCK("metric_double", METRIC_DOUBLE)
270       else break;
271       return 1;
272     case 'n':
273       if(!strcmp(k, "name")) lua_pushstring(L, check->name);
274       else break;
275       return 1;
276     case 'p':
277       if(!strcmp(k, "period")) lua_pushinteger(L, check->period);
278       else break;
279       return 1;
280     case 's':
281       if(!strcmp(k, "status")) {
282         lua_pushlightuserdata(L, check);
283         lua_pushcclosure(L, noit_lua_set_status, 1);
284       }
285       else break;
286       return 1;
287     case 't':
288       if(!strcmp(k, "target")) lua_pushstring(L, check->target);
289       else if(!strcmp(k, "timeout")) lua_pushinteger(L, check->timeout);
290       else break;
291       return 1;
292     case 'u':
293       if(!strcmp(k, "unavailable")) {
294         lua_pushlightuserdata(L, check);
295         lua_pushinteger(L, NP_UNAVAILABLE);
296         lua_pushcclosure(L, noit_lua_set_available, 2);
297       }
298       else break;
299       return 1;
300     default:
301       break;
302   }
303   luaL_error(L, "noit_check_t no such element: %s", k);
304   return 0;
305 }
306 static void
307 noit_lua_setup_module(lua_State *L,
308                       noit_module_t *mod) {
309   noit_module_t **addr;
310   addr = (noit_module_t **)lua_newuserdata(L, sizeof(mod));
311   *addr = mod;
312   if(luaL_newmetatable(L, "noit_module_t") == 1) {
313     lua_pushcclosure(L, noit_module_index_func, 0);
314     lua_setfield(L, -2, "__index");
315   }
316   lua_setmetatable(L, -2);
317 }
318 static void
319 noit_lua_setup_check(lua_State *L,
320                      noit_check_t *check) {
321   noit_check_t **addr;
322   addr = (noit_check_t **)lua_newuserdata(L, sizeof(check));
323   *addr = check;
324   if(luaL_newmetatable(L, "noit_check_t") == 1) {
325     lua_pushcclosure(L, noit_check_index_func, 0);
326     lua_setfield(L, -2, "__index");
327   }
328   lua_setmetatable(L, -2);
329 }
330 static int
331 noit_lua_module_onload(noit_image_t *i) {
332   int rv;
333   lua_State *L;
334   lua_module_closure_t *lmc;
335
336   lmc = noit_image_get_userdata(i);
337   L = lmc->lua_state;
338   lua_getglobal(L, "require");
339   lua_pushstring(L, lmc->object);
340   rv = lua_pcall(L, 1, 1, 0);
341   if(rv) {
342     int i;
343     noitL(nlerr, "lua: %s.onload failed\n", lmc->object);
344     i = lua_gettop(L);
345     if(i>0) {
346       if(lua_isstring(L, i)) {
347         const char *err;
348         size_t len;
349         err = lua_tolstring(L, i, &len);
350         noitL(nlerr, "lua: %s\n", err);
351       }
352     }
353     lua_pop(L,i);
354     return -1;
355   }
356   lua_pop(L, lua_gettop(L));
357
358   noit_lua_pushmodule(L, lmc->object);
359   if(lua_isnil(L, -1)) {
360     lua_pop(L, 1);
361     noitL(nlerr, "lua: no such object %s\n", lmc->object);
362     return -1;
363   }
364   lua_getfield(L, -1, "onload");
365   lua_remove(L, -2);
366   if(!lua_isfunction(L, -1)) {
367     lua_pop(L, 1);
368     /* No onload */
369     return 0;
370   }
371   noit_lua_setup_module(L, (noit_module_t *)i);
372   lua_pcall(L, 1, 1, 0);
373   if(lua_isnumber(L, -1)) {
374     int rv;
375     rv = lua_tointeger(L, -1);
376     lua_pop(L, 1);
377     return rv;
378   } else {
379     lua_pop(L,1);
380     noitL(nlerr, "%s.onload must return a integer\n", lmc->object);
381     return -1;
382   }
383   return 0;
384 }
385 #define LMC_DECL(L, mod) \
386   lua_State *L; \
387   lua_module_closure_t *lmc; \
388   lmc = noit_module_get_userdata(mod); \
389   L = lmc->lua_state
390 #define SETUP_CALL(L, func, failure) do { \
391   noit_lua_pushmodule(L, lmc->object); \
392   lua_getfield(L, -1, func); \
393   lua_remove(L, -2); \
394   if(!lua_isfunction(L, -1)) { \
395     lua_pop(L, 1); \
396     failure; \
397   } \
398 } while(0)
399 #define RETURN_INT(L, func) do { \
400   int base = lua_gettop(L); \
401   assert(base == 1); \
402   if(lua_isnumber(L, -1)) { \
403     int rv; \
404     rv = lua_tointeger(L, -1); \
405     lua_pop(L, 1); \
406     return rv; \
407   } \
408   lua_pop(L,1); \
409   noitL(nlerr, "%s.%s must return a integer\n", lmc->object, func); \
410 } while(0)
411
412 static int
413 noit_lua_module_config(noit_module_t *mod,
414                        noit_hash_table *options) {
415   LMC_DECL(L, mod);
416   SETUP_CALL(L, "config", return 0);
417
418   noit_lua_setup_module(L, mod);
419   noit_lua_hash_to_table(L, options);
420   lua_pcall(L, 2, 1, 0);
421
422   RETURN_INT(L, "config");
423   return -1;
424 }
425 static int
426 noit_lua_module_init(noit_module_t *mod) {
427   LMC_DECL(L, mod);
428   SETUP_CALL(L, "init", return 0);
429
430   noit_lua_setup_module(L, mod);
431   lua_pcall(L, 1, 1, 0);
432
433   RETURN_INT(L, "init");
434   return -1;
435 }
436 static void
437 noit_lua_module_cleanup(noit_module_t *mod, noit_check_t *check) {
438   noit_lua_check_info_t *ci = check->closure;
439   LMC_DECL(L, mod);
440   SETUP_CALL(L, "cleanup", goto clean);
441
442   noit_lua_setup_module(L, mod);
443   noit_lua_setup_check(L, check);
444   lua_pcall(L, 2, 0, 0);
445
446  clean:
447   if(ci) {
448     noit_lua_check_clean_events(ci);
449     free(ci);
450     check->closure = NULL;
451   }
452 }
453
454 /* Here is where the magic starts */
455 static void
456 noit_lua_log_results(noit_module_t *self, noit_check_t *check) {
457   noit_lua_check_info_t *ci = check->closure;
458   struct timeval duration;
459   u_int32_t duration_ms;
460
461   gettimeofday(&ci->finish_time, NULL);
462   sub_timeval(ci->finish_time, check->last_fire_time, &duration);
463
464   memcpy(&ci->current.whence, &ci->finish_time, sizeof(ci->current.whence));
465   ci->current.duration = duration.tv_sec * 1000 + duration.tv_usec / 1000;
466   duration_ms = ci->current.duration;
467
468   noit_check_set_stats(self, check, &ci->current);
469 }
470 int
471 noit_lua_yield(noit_lua_check_info_t *ci, int nargs) {
472   noitL(nldeb, "lua: %p yielding\n", ci->coro_state);
473   return lua_yield(ci->coro_state, nargs);
474 }
475 int
476 noit_lua_resume(noit_lua_check_info_t *ci, int nargs) {
477   int result, base;
478   noit_check_t *check;
479   check = ci->check;
480
481   noitL(nldeb, "lua: %p resuming\n", ci->coro_state);
482   result = lua_resume(ci->coro_state, nargs);
483   switch(result) {
484     case 0: /* success */
485       break;
486     case LUA_YIELD: /* The complicated case */
487       /* The person yielding had better setup an event
488        * to wake up the coro...
489        */
490       goto done;
491     default: /* Errors */
492       noitL(nlerr, "lua resume returned: %d\n", result);
493       ci->current.status = ci->timed_out ? "timeout" : "unknown error";
494       ci->current.available = NP_UNAVAILABLE;
495       ci->current.state = NP_BAD;
496       base = lua_gettop(ci->coro_state);
497       if(base>0) {
498         if(lua_isstring(ci->coro_state, base)) {
499           const char *err;
500           err = lua_tostring(ci->coro_state, base);
501           if(err) ci->current.status = (char *)err;
502         }
503       }
504       break;
505   }
506   noit_lua_log_results(ci->self, ci->check);
507   noit_lua_module_cleanup(ci->self, ci->check);
508   check->flags &= ~NP_RUNNING;
509
510   lua_getglobal(ci->lmc->lua_state, "noit_coros");
511   luaL_unref(ci->lmc->lua_state, -1, ci->coro_state_ref);
512   lua_pop(ci->lmc->lua_state, 1);
513
514  done:
515   lua_gc(ci->lmc->lua_state, LUA_GCCOLLECT, 0);
516   return result;
517 }
518 static int
519 noit_lua_check_timeout(eventer_t e, int mask, void *closure,
520                        struct timeval *now) {
521   noit_check_t *check;
522   noit_lua_check_info_t *ci = closure;
523   check = ci->check;
524   noitL(nldeb, "lua: %p ->check_timeout\n", ci->coro_state);
525   ci->timed_out = 1;
526   noit_lua_check_deregister_event(ci, e, 0);
527   if(ci->coro_state) {
528     /* Our coro is still "in-flight". To fix this we will unreference
529      * it, garbage collect it and then ensure that it failes a resume
530      */
531     lua_getglobal(ci->lmc->lua_state, "noit_coros");
532     luaL_unref(ci->lmc->lua_state, -1, ci->coro_state_ref);
533     lua_pop(ci->lmc->lua_state, 1);
534     lua_gc(ci->lmc->lua_state, LUA_GCCOLLECT, 0);
535     assert(2 == noit_lua_resume(ci, 0));
536   } else {
537     noit_lua_log_results(ci->self, ci->check);
538     noit_lua_module_cleanup(ci->self, ci->check);
539     check->flags &= ~NP_RUNNING;
540   }
541   return 0;
542 }
543 static int
544 noit_lua_initiate(noit_module_t *self, noit_check_t *check) {
545   LMC_DECL(L, self);
546   noit_lua_check_info_t *ci;
547   struct timeval p_int, __now;
548   eventer_t e;
549
550   if(!check->closure) check->closure = calloc(1, sizeof(noit_lua_check_info_t));
551   ci = check->closure;
552
553   /* We cannot be running */
554   assert(!(check->flags & NP_RUNNING));
555   check->flags |= NP_RUNNING;
556
557   ci->self = self;
558   ci->check = check;
559   noit_check_stats_clear(&ci->current);
560
561   gettimeofday(&__now, NULL);
562   memcpy(&check->last_fire_time, &__now, sizeof(__now));
563
564   e = eventer_alloc();
565   e->mask = EVENTER_TIMER;
566   e->callback = noit_lua_check_timeout;
567   e->closure = ci;
568   memcpy(&e->whence, &__now, sizeof(__now));
569   p_int.tv_sec = check->timeout / 1000;
570   p_int.tv_usec = (check->timeout % 1000) * 1000;
571   add_timeval(e->whence, p_int, &e->whence);
572   noit_lua_check_register_event(ci, e);
573   eventer_add(e);
574
575   noitL(nlerr, "initiate gettop => %d\n", lua_gettop(L));
576   ci->lmc = lmc;
577   lua_getglobal(L, "noit_coros");
578   ci->coro_state = lua_newthread(L);
579   ci->coro_state_ref = luaL_ref(L, -2);
580   lua_pop(L, 1); /* pops noit_coros */
581   noit_hash_store(&noit_coros,
582                   (const char *)&ci->coro_state, sizeof(ci->coro_state),
583                   ci);
584
585   SETUP_CALL(ci->coro_state, "initiate", goto fail);
586   noit_lua_setup_module(ci->coro_state, ci->self);
587   noit_lua_setup_check(ci->coro_state, ci->check);
588   noit_lua_resume(ci, 2);
589
590   return 0;
591
592  fail:
593   noit_lua_log_results(ci->self, ci->check);
594   noit_lua_module_cleanup(ci->self, ci->check);
595   check->flags &= ~NP_RUNNING;
596   return -1;
597 }
598 /* This is the standard wrapper */
599 static int
600 noit_lua_module_initiate_check(noit_module_t *self, noit_check_t *check,
601                                int once, noit_check_t *cause) {
602   if(!check->closure) check->closure = calloc(1, sizeof(noit_lua_check_info_t));
603   INITIATE_CHECK(noit_lua_initiate, self, check);
604   return 0;
605 }
606 static noit_module_t *
607 noit_lua_loader_load(noit_module_loader_t *loader,
608                      char *module_name,
609                      noit_conf_section_t section) {
610   noit_module_t *m;
611   lua_State *L;
612   lua_module_closure_t *lmc;
613   char *object;
614  
615   noitL(nldeb, "Loading lua module: %s\n", module_name);
616   if(noit_conf_get_string(section, "@object", &object) == 0) {
617     noitL(nlerr, "Lua module %s require object attribute.\n", module_name);
618     return NULL;
619   }
620
621   m = noit_blank_module();
622   m->hdr.magic = NOIT_MODULE_MAGIC;
623   m->hdr.version = NOIT_MODULE_ABI_VERSION;
624   m->hdr.name = strdup(module_name);
625   m->hdr.description = strdup("Lua module");
626   m->hdr.onload = noit_lua_module_onload;
627   lmc = calloc(1, sizeof(*lmc));
628   lmc->object = object;
629
630   L = lmc->lua_state = lua_open();
631
632
633   lua_gc(L, LUA_GCSTOP, 0);  /* stop collector during initialization */
634   luaL_openlibs(L);  /* open libraries */
635   luaopen_noit(L);
636   lua_newtable(L);
637   lua_setglobal(L, "noit_coros");
638
639   lua_getfield(L, LUA_GLOBALSINDEX, "package");
640   lua_pushfstring(L, "%s", noit_lua_loader_get_directory(loader));
641   lua_setfield(L, -2, "path");
642   lua_pop(L, 1);
643
644   lua_gc(L, LUA_GCRESTART, 0);
645
646   noit_image_set_userdata(&m->hdr, lmc);
647   if(m->hdr.onload(&m->hdr) == -1) {
648     free(m->hdr.name);
649     free(m->hdr.description);
650     free(lmc->object);
651     free(lmc);
652     /* FIXME: We leak the opaque_handler in the module here... */
653     free(m);
654     return NULL;
655   }
656
657   m->config = noit_lua_module_config;
658   m->init = noit_lua_module_init;
659   m->initiate_check = noit_lua_module_initiate_check;
660   m->cleanup = noit_lua_module_cleanup;
661
662   noit_register_module(m);
663   return m;
664 }
665
666 static int
667 noit_lua_loader_config(noit_module_loader_t *self, noit_hash_table *o) {
668   char *dir = ".";
669   noit_hash_retrieve(o, "directory", strlen("directory"), (void **)&dir);
670   noit_lua_loader_set_directory(self, dir);
671   return 0;
672 }
673 static int
674 noit_lua_loader_onload(noit_image_t *self) {
675   nlerr = noit_log_stream_find("error/serf");
676   nldeb = noit_log_stream_find("debug/serf");
677   if(!nlerr) nlerr = noit_stderr;
678   if(!nldeb) nldeb = noit_debug;
679   return 0;
680 }
681
682 noit_module_loader_t lua = {
683   {
684     NOIT_LOADER_MAGIC,
685     NOIT_LOADER_ABI_VERSION,
686     "lua",
687     "Lua check loader",
688     noit_lua_loader_onload,
689   },
690   noit_lua_loader_config,
691   NULL,
692   noit_lua_loader_load
693 };
Note: See TracBrowser for help on using the browser.