My Project
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
haproxy.c
Go to the documentation of this file.
1 /*
2 START OF LICENSE STUB
3  DeDOS: Declarative Dispersion-Oriented Software
4  Copyright (C) 2017 University of Pennsylvania, Georgetown University
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 END OF LICENSE STUB
19 */
20 #include <unistd.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <sys/wait.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <fcntl.h>
28 #include "msu_ids.h"
29 #include "runtime_communication.h"
30 #include "logging.h"
31 #define SOCAT "/usr/bin/socat"
32 
33 char *socat_cmd[] = {SOCAT, "stdio", "/tmp/haproxy.socket", NULL};
34 
35 #define SOCAT_INPUT "set weight https/s%d %d\r\n"
36 
37 #define WRITE_END 1
38 #define READ_END 0
39 
40 int reweight_haproxy(int server, int weight){
41 
42  int fd[2];
43  int rtn = pipe(fd);
44  if (rtn < 0) {
45  log_error("Error creating pipe");
46  return -1;
47  }
48 
49  pid_t pid = fork();
50 
51  if (pid == 0) {
52  dup2(fd[READ_END], STDIN_FILENO);
53  int dev_null = open("/dev/null", O_WRONLY);
54  dup2(dev_null, STDOUT_FILENO);
55  close(fd[WRITE_END]);
56  execv(SOCAT, socat_cmd);
57  close(fd[READ_END]);
58  log_error("Failed to execute '%s'\n", SOCAT);
59  exit(1);
60  } else {
61  int status;
62  FILE *f = fdopen(fd[WRITE_END], "w");
63  if (f == NULL) {
64  log_error("Error opening FILE to pipe");
65  }
66  int rtn = fprintf(f, SOCAT_INPUT, server, weight);
67  if (rtn == -1) {
68  perror("fprintf");
69  }
70  fclose(f);
71  close(fd[READ_END]);
72  waitpid(pid, &status, 0);
73  }
74  return 0;
75 }
76 
77 #define N_QLEN_SAMPLES 10
78 
79 // TODO
80 //
81 /*
82 static int get_read_qlens(double *qlens, int n_qlens) {
83  struct dfg_msu_type *type = get_dfg_msu_type(WEBSERVER_READ_MSU_TYPE_ID);
84  if (type == NULL) {
85  return 0;
86  }
87  for (int i=0; i < type->n_instances; i++) {
88  struct dfg_msu *instance = type->instances[i];
89  int rt_id = instance->scheduling.runtime->id;
90  if (rt_id > n_qlens) {
91  log_error("Cannot fit all runtimes in qlens");
92  return -1;
93  }
94  struct timed_rrdb *stat = get_stat(MSU_QUEUE_LEN, instance->id);
95  double mean = average_n(stat, N_QLEN_SAMPLES);
96  if (qlens[rt_id] < 0) {
97  qlens[rt_id] = 1;
98  }
99  }
100 }
101 */
102 void set_haproxy_weights(int rt_id, int offset) {
103  int n_reads[MAX_RUNTIMES+1];
104  for (int i=0; i< MAX_RUNTIMES + 1; i++) {
105  if (runtime_fd(i) > 0) {
106  if (i == rt_id) {
107  n_reads[i] = -offset;
108  } else {
109  n_reads[i] = 0;
110  }
111  } else {
112  n_reads[i] = -1;
113  }
114  }
116  if (type == NULL) {
117  log_error("Error getting read type");
118  return;
119  }
120  for (int i=0; i<type->n_instances; i++) {
121  int rt_id = type->instances[i]->scheduling.runtime->id;
122  n_reads[rt_id]++;
123  }
124 
125  for (int i=0; i <= MAX_RUNTIMES; i++) {
126  if (n_reads[i] >= 0) {
127  reweight_haproxy(i, n_reads[i]);
128  }
129  }
130 }
131 
132 
char * socat_cmd[]
Definition: haproxy.c:33
#define READ_END
Definition: haproxy.c:38
struct dfg_scheduling scheduling
Information about where an MSU is scheduled.
Definition: dfg.h:225
struct dfg_msu * instances[512]
Each instance of this MSU type.
Definition: dfg.h:186
int id
Unique identifier for the runtime.
Definition: dfg.h:74
Logging of status messages to the terminal.
#define WRITE_END
Definition: haproxy.c:37
struct dfg_runtime * runtime
The runtime on which an MSU is running.
Definition: dfg.h:117
#define log_error(fmt,...)
Definition: logging.h:101
A type of MSU.
Definition: dfg.h:176
int runtime_fd(unsigned int runtime_id)
#define SOCAT_INPUT
Definition: haproxy.c:35
#define WEBSERVER_READ_MSU_TYPE_ID
Definition: msu_ids.h:25
void set_haproxy_weights(int rt_id, int offset)
Definition: haproxy.c:102
int reweight_haproxy(int server, int weight)
Definition: haproxy.c:40
int n_instances
The number of instances of this MSU type.
Definition: dfg.h:187
struct dfg_msu_type * get_dfg_msu_type(unsigned int id)
Returns the MSU type with the given ID.
Definition: dfg.c:68
#define MAX_RUNTIMES
The maximum number of runtimes that may be present in the DFG.
Definition: dfg.h:45
#define SOCAT
Definition: haproxy.c:31