1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <signal.h>
8 #include <getopt.h>
9 #include <string.h>
10
11 #include <rte_lcore.h>
12 #include <rte_power.h>
13 #include <rte_debug.h>
14 #include <rte_eal.h>
15 #include <rte_log.h>
16
17 #include "vm_power_cli_guest.h"
18 #include "parse.h"
19
20 static void
sig_handler(int signo)21 sig_handler(int signo)
22 {
23 printf("Received signal %d, exiting...\n", signo);
24 unsigned lcore_id;
25
26 RTE_LCORE_FOREACH(lcore_id) {
27 rte_power_exit(lcore_id);
28 }
29
30 }
31
32 #define MAX_HOURS 24
33
34 /* Parse the argument given in the command line of the application */
35 static int
parse_args(int argc,char ** argv)36 parse_args(int argc, char **argv)
37 {
38 int opt, ret;
39 char **argvopt;
40 int option_index;
41 char *prgname = argv[0];
42 const struct option lgopts[] = {
43 { "vm-name", required_argument, 0, 'n'},
44 { "busy-hours", required_argument, 0, 'b'},
45 { "quiet-hours", required_argument, 0, 'q'},
46 { "port-list", required_argument, 0, 'p'},
47 { "vcpu-list", required_argument, 0, 'l'},
48 { "policy", required_argument, 0, 'o'},
49 {NULL, 0, 0, 0}
50 };
51 struct channel_packet *policy;
52 unsigned short int hours[MAX_HOURS];
53 unsigned short int cores[MAX_VCPU_PER_VM];
54 unsigned short int ports[MAX_VCPU_PER_VM];
55 int i, cnt, idx;
56
57 policy = get_policy();
58 ret = set_policy_defaults(policy);
59 if (ret != 0) {
60 printf("Failed to set policy defaults\n");
61 return -1;
62 }
63
64 argvopt = argv;
65
66 while ((opt = getopt_long(argc, argvopt, "n:b:q:p:",
67 lgopts, &option_index)) != EOF) {
68
69 switch (opt) {
70 /* portmask */
71 case 'n':
72 strlcpy(policy->vm_name, optarg, VM_MAX_NAME_SZ);
73 printf("Setting VM Name to [%s]\n", policy->vm_name);
74 break;
75 case 'b':
76 case 'q':
77 //printf("***Processing set using [%s]\n", optarg);
78 cnt = parse_set(optarg, hours, MAX_HOURS);
79 if (cnt < 0) {
80 printf("Invalid value passed to quiet/busy hours - [%s]\n",
81 optarg);
82 break;
83 }
84 idx = 0;
85 for (i = 0; i < MAX_HOURS; i++) {
86 if (hours[i]) {
87 if (opt == 'b') {
88 printf("***Busy Hour %d\n", i);
89 policy->timer_policy.busy_hours
90 [idx++] = i;
91 } else {
92 printf("***Quiet Hour %d\n", i);
93 policy->timer_policy.quiet_hours
94 [idx++] = i;
95 }
96 }
97 }
98 break;
99 case 'l':
100 cnt = parse_set(optarg, cores, MAX_VCPU_PER_VM);
101 if (cnt < 0) {
102 printf("Invalid value passed to vcpu-list - [%s]\n",
103 optarg);
104 break;
105 }
106 idx = 0;
107 for (i = 0; i < MAX_VCPU_PER_VM; i++) {
108 if (cores[i]) {
109 printf("***Using core %d\n", i);
110 policy->vcpu_to_control[idx++] = i;
111 }
112 }
113 policy->num_vcpu = idx;
114 printf("Total cores: %d\n", idx);
115 break;
116 case 'p':
117 cnt = parse_set(optarg, ports, MAX_VCPU_PER_VM);
118 if (cnt < 0) {
119 printf("Invalid value passed to port-list - [%s]\n",
120 optarg);
121 break;
122 }
123 idx = 0;
124 for (i = 0; i < MAX_VCPU_PER_VM; i++) {
125 if (ports[i]) {
126 printf("***Using port %d\n", i);
127 if (set_policy_mac(i, idx++) != 0) {
128 printf("Cannot set policy MAC");
129 return -1;
130 }
131 }
132 }
133 policy->nb_mac_to_monitor = idx;
134 printf("Total Ports: %d\n", idx);
135 break;
136 case 'o':
137 if (!strcmp(optarg, "TRAFFIC"))
138 policy->policy_to_use = TRAFFIC;
139 else if (!strcmp(optarg, "TIME"))
140 policy->policy_to_use = TIME;
141 else if (!strcmp(optarg, "WORKLOAD"))
142 policy->policy_to_use = WORKLOAD;
143 else if (!strcmp(optarg, "BRANCH_RATIO"))
144 policy->policy_to_use = BRANCH_RATIO;
145 else {
146 printf("Invalid policy specified: %s\n",
147 optarg);
148 return -1;
149 }
150 break;
151 /* long options */
152
153 case 0:
154 break;
155
156 default:
157 return -1;
158 }
159 }
160
161 if (optind >= 0)
162 argv[optind-1] = prgname;
163
164 ret = optind-1;
165 optind = 0; /* reset getopt lib */
166 return ret;
167 }
168
169 int
main(int argc,char ** argv)170 main(int argc, char **argv)
171 {
172 int ret;
173 unsigned lcore_id;
174
175 ret = rte_eal_init(argc, argv);
176 if (ret < 0)
177 rte_panic("Cannot init EAL\n");
178
179 signal(SIGINT, sig_handler);
180 signal(SIGTERM, sig_handler);
181
182 argc -= ret;
183 argv += ret;
184
185 /* parse application arguments (after the EAL ones) */
186 ret = parse_args(argc, argv);
187 if (ret < 0)
188 rte_exit(EXIT_FAILURE, "Invalid arguments\n");
189
190 rte_power_set_env(PM_ENV_KVM_VM);
191 RTE_LCORE_FOREACH(lcore_id) {
192 rte_power_init(lcore_id);
193 }
194 run_cli(NULL);
195
196 return 0;
197 }
198