source: research/2008-displacement/main-cpushare @ 2286

Last change on this file since 2286 was 2286, checked in by Sam Hocevar, 15 years ago
  • More scripts for part 3.
  • Implemented main.c as a seccomp bytecode for CPUShare.
  • Property svn:executable set to *
File size: 3.9 KB
Line 
1#! /usr/bin/python
2
3import os, struct, sys, random
4
5import gd
6
7from cpushare.proto_const import *
8from cpushare.exceptions import CompilationError
9
10# Our input data
11source = False
12result = False
13todo = 0
14
15# Parse command line
16if len(sys.argv) < 4:
17    print 'Usage: %s <buy_order.cpu> -<mode> [image list]' % (sys.argv[0],)
18    sys.exit(-1)
19mode = sys.argv[2][1]
20source = sys.argv[3:]
21result = [False] * len(source)
22
23class buy_state_machine_class(object):
24    buy_api = '0.0.0'
25
26    w, h = 0, 0
27    index = -1
28    answer = ''
29
30    def __init__(self, protocol):
31        self.protocol = protocol
32        self.handler = self.stringReceived
33
34    def start(self):
35        global todo, source
36        if todo >= len(source):
37            return # We're finished... FIXME: a process is stuck
38        self.index = todo
39        todo += 1
40        gd.gdMaxColors = 256 * 256 * 256
41        im = gd.image(source[self.index])
42        # Send mode
43        self.protocol.sendString(PROTO_SECCOMP_FORWARD + mode)
44        # Send image size
45        (self.w, self.h) = (w, h) = im.size()
46        print 'sending %s (%dx%d)' % (source[self.index], w, h)
47        msg = chr(w / 256) + chr(w % 256) + chr(h / 256) + chr(h % 256)
48        self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg)
49        # Send image contents
50        msg = ''
51        for y in range(h):
52            for x in range(w):
53                p = im.getPixel((x, y))
54                rgb = im.colorComponents(p)
55                msg += chr(rgb[1]) # use green coordinate
56        self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg)
57        print '%s bytes sent' % len(msg)
58
59    def stringReceived(self, string):
60        control = string[0]
61        data = string[1:]
62
63        if control == PROTO_SECCOMP_FORWARD:
64            self.answer += data
65            if ord(self.answer[-1]) != 0:
66                return
67            global result
68            result[self.index] = self.answer[:-1]
69            print self.answer[:-1],
70            self.protocol.sendString(PROTO_SECCOMP_SUCCESS)
71            # the PROTO_SECCOMP_SUCCESS probably won't have a chance
72            # to go out but it doesn't matter because we'll disconnect
73            # not just this but all other seccomp state machines too
74            from twisted.internet import reactor
75            reactor.stop()
76        elif control == PROTO_SECCOMP_SIGNAL:
77            print 'Checkpoint starting'
78        elif control == PROTO_LOG:
79            print repr(data)
80        else:
81            if control == PROTO_SECCOMP_SUCCESS:
82                pass
83            elif control == PROTO_SECCOMP_FAILURE:
84                status = struct.unpack('!i', data)[0]
85                exit_code = status >> 8
86                signal = status & 0xff
87                s = 'Seccomp failure: status %d, exit_code %d, signal %d.' % \
88                      (status, exit_code, signal)
89                print s
90            else:
91                s = 'Unknown failure %d - %s' % (ord(control), repr(string))
92                self.protocol.sendString(PROTO_SECCOMP_FAILURE + s)
93                print s
94            self.protocol.sendString(PROTO_SECCOMP_FAILURE)
95            self.protocol.transport.loseConnection()
96
97    def connectionLost(self):
98        pass
99
100# Build local module
101from new import module
102m = module('cpushare_buy')
103
104# Create bytecode -- i686 only
105from cpushare.seccomp_gen import seccomp_gen_class
106m.seccomp_gen_hash = {}
107m.seccomp_gen_hash['i686'] = seccomp_gen_class('bytecode', 'i686')
108m.seccomp_gen_hash['i686'].heap_kbytes = 1
109m.seccomp_gen_hash['i686'].stack_kbytes = 1
110
111# Estimate of the max number of seconds that the sell client
112# will take to checkpoint and send its state back to us
113m.checkpoint_sec = 10
114
115# Our buying state machine
116m.buy_state_machine_class = buy_state_machine_class
117
118# Append our module to the global list of modules
119sys.modules['cpushare_buy'] = m
120
121# Build a new command line and run twistd
122sys.argv = [sys.argv[0], '-q', '-n', 'cpushare', '--order', sys.argv[1]]
123from twisted.scripts.twistd import run
124run()
125
Note: See TracBrowser for help on using the repository browser.