Bump version to 0.3.5next
[archipelago] / xseg / peers / user / monitor.c
1 /*
2  * Copyright 2012 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *   2. Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer in the documentation and/or other materials
14  *      provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * The views and conclusions contained in the software and
30  * documentation are those of the authors and should not be
31  * interpreted as representing official policies, either expressed
32  * or implied, of GRNET S.A.
33  */
34
35 #include <stdio.h>
36 #include <unistd.h>
37 #include <sys/types.h>
38 #include <pthread.h>
39 #include <xseg/xseg.h>
40 #include <peer.h>
41 #include <sys/time.h>
42
43 #define INPUT_BUF_SIZE 256
44 #define MAX_NR_ARGS 100
45
46 struct monitord {
47         uint32_t mon_portno;
48 };
49
50 struct monitor_io {
51         uint32_t src_portno;
52         void *src_priv;
53 };
54
55 void custom_peer_usage()
56 {
57         return;
58 }
59
60 static int forward(struct peerd *peer, struct peer_req *pr)
61 {
62         int r;
63         r = submit_peer_req(peer, pr);
64         if (r < 0) {
65                 printf("couldn't forward request");
66                 return -1;
67         }
68         return 0;
69 }
70
71 static int complete_forwarded(struct peerd *peer, struct peer_req *pr)
72 {
73         struct xseg_request *req = pr->req;
74
75         // assert mio->src_portno != NoPort
76         if (req->state & XS_SERVED)
77                 complete(peer, pr);
78         else if (req->state & XS_FAILED)
79                 fail (peer, pr);
80         else {
81                 printf("invalid state\n");
82                 return -1;
83         }
84         return 0;
85 }
86
87 int dispatch(struct peerd *peer, struct peer_req *pr, struct xseg_request *xreq,
88                 enum dispatch_reason reason)
89 {
90         struct xseg_request *req = pr->req;
91         if (req->state & (XS_SERVED | XS_FAILED)){
92                 log_pr("completing", pr);
93                 complete_forwarded(peer, pr);
94         }
95         else {
96                 log_pr("forwarding", pr);
97                 forward(peer,pr);
98         }
99         return 0;
100 }
101
102 int mpause(struct peerd *peer)
103 {
104         struct xseg *xseg = peer->xseg;
105         struct xseg_port *port = xseg_get_port(xseg, peer->portno_start);
106         if (!port)
107                 return -1;
108         
109         xlock_acquire(&port->rq_lock, peer->portno_start);
110         xlock_acquire(&port->pq_lock, peer->portno_start);
111         return 0;
112 }
113
114 int munpause(struct peerd *peer)
115 {
116         struct xseg *xseg = peer->xseg;
117         struct xseg_port *port = xseg_get_port(xseg, peer->portno_start);
118         if (!port)
119                 return -1;
120         
121         xlock_release(&port->rq_lock);
122         xlock_release(&port->pq_lock);
123         return 0;
124 }
125
126 struct peerd *main_peer;
127
128 void main_loop(void)
129 {
130         int ret;
131         struct peerd * peer = main_peer;
132         char buf[INPUT_BUF_SIZE];
133         char *nl;
134
135         unsigned int portno = NoPort, dstgw, srcgw;
136
137         for (;;){
138                 printf("waitin next line\n");
139                 if (fgets(buf, INPUT_BUF_SIZE, stdin)) {
140                         nl = strchr(buf, '\n');
141                         if (nl)
142                                 *nl = 0;
143                         buf[INPUT_BUF_SIZE -1] = 0;
144                         printf("got line input\n");
145                         ret = sscanf(buf, "set srcgw %u %u", &portno, &srcgw);
146                         if (ret == 2){
147                                 printf("found setsrcgw\n");
148                                 xseg_set_srcgw(peer->xseg, (uint32_t) portno, (uint32_t) srcgw);
149                                 continue;
150                         };
151                         ret = sscanf(buf, "set dstgw %u %u", &portno, &dstgw);
152                         if (ret == 2){
153                                 printf("found set dstgw\n");
154                                 xseg_set_dstgw(peer->xseg, (uint32_t) portno, (uint32_t) dstgw);
155                                 continue;
156                         };
157                         ret = sscanf(buf, "getandset srcgw %u %u", &portno, &srcgw);
158                         if (ret == 2){
159                                 printf("found getand set srcgw\n");
160                                 xseg_getandset_srcgw(peer->xseg, (uint32_t) portno, (uint32_t) srcgw);
161                                 continue;
162                         };
163                         ret = sscanf(buf, "getandset dstgw %u %u", &portno, &dstgw);
164                         if (ret == 2){
165                                 printf("found getandset dstgw\n");
166                                 xseg_getandset_dstgw(peer->xseg, (uint32_t) portno, (uint32_t) dstgw);
167                                 continue;
168                         };
169                         ret = sscanf(buf, "pause %u", &portno);
170                         if (ret == 1){
171                                 printf("found pause\n");
172                                 mpause(peer);
173                                 continue;
174                         };
175                         ret = sscanf(buf, "unpause %u", &portno);
176                         if (ret == 1){
177                                 printf("found unpause\n");
178                                 munpause(peer);
179                                 continue;
180                         };
181                 }
182                 else
183                         exit(0);
184         }
185 }
186
187 int custom_peer_init(struct peerd *peer, int argc, char *argv[])
188 {
189         int i;
190         struct monitor_io *mio;
191         struct monitord *monitor;
192
193         monitor = malloc(sizeof(struct monitord));
194         if (!monitor)
195                 return -1;
196         peer->priv = monitor;
197         monitor->mon_portno = NoPort;
198         
199         
200         for (i = 0; i < peer->nr_ops; i++) {
201                 mio = malloc(sizeof(struct monitor_io));
202                 if (!mio)
203                         return -1;
204                 peer->peer_reqs[i].priv = mio;
205                 mio->src_portno = NoPort;
206         }
207         
208         for (i = 1; i < argc; i++) {
209                 if (!strcmp(argv[i], "-mp") && (i + 1 < argc)) {
210                         monitor->mon_portno = atoi(argv[i+1]);
211                         i+=1;
212                         continue;
213                 }
214         }
215         main_peer = peer;
216
217         peer->interactive_func = main_loop;
218
219         return 0;
220 }
221
222 void custom_peer_finalize(struct peerd *peer)
223 {
224         return;
225 }