rewrite mt-mapperd based on st threads
[archipelago] / xseg / peers / user / mapperd.py
1 #!/usr/bin/env python2.7
2 # The *Python* Mapper
3 import sys, argparse
4 # FIXME:
5 sys.path.append("/root/archip/xseg/sys/user/python")
6 from xseg import xseg_api as xseg
7 from xseg import xprotocol
8
9 cb_null_ptrtype = xseg.CFUNCTYPE(None, xseg.POINTER(xseg.xseg), xseg.uint32_t)
10
11 # FIXME: Error handling
12 def perr(errbuf):
13     print >> sys.stderr, errbuf
14     sys.exit(-1)
15
16 def mapper_loop(port, ctx):
17     while True:
18         if xseg.xseg_prepare_wait(ctx, port) != 0:
19             perr("prepare_wait\n")
20
21         xreqp = xseg.xseg_accept(ctx, port)
22         try:
23             xreq = xreqp.contents
24         except ValueError:
25             xseg.xseg_wait_signal(ctx, 1000)
26             continue
27
28         xseg.xseg_cancel_wait(ctx, port)
29
30         if xseg.sizeof(xprotocol.xseg_reply_map) + xseg.sizeof(xprotocol.xseg_reply_map_scatterlist) > xreq.datalen:
31             perr("datalen\n")
32         if xreq.targetlen > xprotocol.XSEG_MAX_TARGETLEN:
33             perr("targetlen\n")
34
35         mreplyp = xseg.cast(xreq.data, xseg.POINTER(xprotocol.xseg_reply_map))
36         try:
37             mreply = mreplyp.contents
38         except ValueError:
39             perr("mreply\n")
40
41         mreply.cnt = 1
42         
43         segsp = xseg.cast(mreply.segs, xseg.POINTER(xprotocol.xseg_reply_map_scatterlist))
44         try:
45             segs = segsp.contents
46         except ValueError:
47             perr("segs\n")
48
49         segs.offset = xreq.offset
50         segs.size = xreq.size
51         tmp = xseg.string_at(xreq.target, xreq.targetlen)
52         segs.target = tmp
53         
54         xreq.state |= xseg.XS_SERVED
55         if xseg.xseg_respond(ctx, xreq.portno, xreq) == xseg.NoSerial:
56             perr("xseg_respond\n")
57         
58         if xseg.xseg_signal(ctx, xreq.portno) != 0:
59             perr("xseg_signal")
60
61 def mapper_init(port, spec):
62     if xseg.xseg_initialize() < 0:
63         perr("xseg_initialize")
64     
65     xconf = xseg.xseg_config()
66     xseg.xseg_parse_spec(spec, xconf)
67
68     ctx = xseg.xseg_join(xconf.type, xconf.name, "posix", xseg.cast(0, cb_null_ptrtype))
69     try:
70        ctx.contents
71     except ValueError:
72         xseg.xseg_finalize()
73         perr("xseg_join")
74     
75     xseg.xseg_bind_port(ctx, port)
76
77     return ctx
78
79 def parse_cmdline():
80     parser = argparse.ArgumentParser(description='mapper')
81
82     parser.add_argument('-p', '--port', type=int, nargs='?', help='mapper port')
83     parser.add_argument('-b', '--bport', type=int, nargs='?', help='blocker port')
84     parser.add_argument('-g', '--spec', type=str, nargs='?', help='xseg segment spec')
85
86     return parser.parse_args()
87
88 def validate_cmdline(args):
89     if args.port < 0:
90         perr("invalid port specified")
91     if args.spec == None:
92         perr ("invalid spec")
93
94 if __name__ == '__main__':
95     args = parse_cmdline()
96     validate_cmdline(args)
97
98     ctx = mapper_init(args.port, args.spec)
99     
100     mapper_loop(args.port, ctx)