]>
Commit | Line | Data |
---|---|---|
2dce8c42 DB |
1 | /* |
2 | Compile server client functions | |
01fb72a0 | 3 | Copyright (C) 2010-2017 Red Hat Inc. |
2dce8c42 DB |
4 | |
5 | This file is part of systemtap, and is free software. You can | |
6 | redistribute it and/or modify it under the terms of the GNU General | |
7 | Public License (GPL); either version 2, or (at your option) any | |
8 | later version. | |
9 | */ | |
c4fd15b4 DB |
10 | |
11 | // Completely disable the client if NSS is not available. | |
2dce8c42 DB |
12 | #include "config.h" |
13 | #include "session.h" | |
005df4e5 | 14 | #include "cscommon.h" |
aa4d21c0 | 15 | #include "csclient.h" |
01fb72a0 DS |
16 | #include "client-nss.h" |
17 | #include "client-http.h" | |
2fad97fd | 18 | #include "util.h" |
0f5d597d | 19 | #include "stap-probe.h" |
2dce8c42 | 20 | |
6b314d31 | 21 | #include <unistd.h> |
01fb72a0 | 22 | #include <iostream> |
79efe7f8 FCE |
23 | |
24 | extern "C" { | |
01fb72a0 | 25 | #include <sys/times.h> |
3eee0879 | 26 | #include <sys/time.h> |
aeb9cc10 | 27 | } |
2fad97fd | 28 | |
aeb9cc10 DB |
29 | using namespace std; |
30 | ||
01fb72a0 DS |
31 | int |
32 | compile_server_client::passes_0_4 () | |
840e5073 | 33 | { |
01fb72a0 DS |
34 | // Use the correct backend. |
35 | #ifdef HAVE_HTTP_SUPPORT | |
36 | if (! s.http_servers.empty()) | |
37 | backend = new http_client_backend (s); | |
840e5073 | 38 | #endif |
01fb72a0 DS |
39 | #if HAVE_NSS |
40 | if (backend == NULL) | |
41 | backend = new nss_client_backend (s); | |
840e5073 | 42 | #endif |
01fb72a0 | 43 | if (backend == NULL) |
840e5073 | 44 | { |
01fb72a0 DS |
45 | clog << _("Using a compile server backend failed.") << endl; |
46 | return 1; | |
840e5073 DB |
47 | } |
48 | ||
0f5d597d | 49 | PROBE1(stap, client__start, &s); |
2fad97fd | 50 | |
aa4d21c0 | 51 | // arguments parsed; get down to business |
4e78c716 | 52 | if (s.verbose || ! s.auto_server_msgs.empty ()) |
a46f9abe | 53 | clog << _("Using a compile server.") << endl; |
aa4d21c0 | 54 | |
aa4d21c0 DB |
55 | struct tms tms_before; |
56 | times (& tms_before); | |
57 | struct timeval tv_before; | |
58 | gettimeofday (&tv_before, NULL); | |
59 | ||
2fad97fd DB |
60 | // Create the request package. |
61 | int rc = initialize (); | |
e19ebcf7 | 62 | assert_no_interrupts(); |
985892de | 63 | if (rc != 0) goto done; |
2fad97fd | 64 | rc = create_request (); |
e19ebcf7 | 65 | assert_no_interrupts(); |
985892de | 66 | if (rc != 0) goto done; |
01fb72a0 | 67 | rc = backend->package_request (); |
e19ebcf7 | 68 | assert_no_interrupts(); |
985892de | 69 | if (rc != 0) goto done; |
2fad97fd DB |
70 | |
71 | // Submit it to the server. | |
01fb72a0 | 72 | rc = backend->find_and_connect_to_server (); |
e19ebcf7 | 73 | assert_no_interrupts(); |
985892de | 74 | if (rc != 0) goto done; |
2fad97fd DB |
75 | |
76 | // Unpack and process the response. | |
01fb72a0 | 77 | rc = backend->unpack_response (); |
e19ebcf7 | 78 | assert_no_interrupts(); |
985892de | 79 | if (rc != 0) goto done; |
01fb72a0 | 80 | rc = backend->process_response (); |
2fad97fd DB |
81 | |
82 | done: | |
aa4d21c0 DB |
83 | struct tms tms_after; |
84 | times (& tms_after); | |
85 | unsigned _sc_clk_tck = sysconf (_SC_CLK_TCK); | |
86 | struct timeval tv_after; | |
87 | gettimeofday (&tv_after, NULL); | |
88 | ||
89 | #define TIMESPRINT "in " << \ | |
90 | (tms_after.tms_cutime + tms_after.tms_utime \ | |
91 | - tms_before.tms_cutime - tms_before.tms_utime) * 1000 / (_sc_clk_tck) << "usr/" \ | |
92 | << (tms_after.tms_cstime + tms_after.tms_stime \ | |
93 | - tms_before.tms_cstime - tms_before.tms_stime) * 1000 / (_sc_clk_tck) << "sys/" \ | |
94 | << ((tv_after.tv_sec - tv_before.tv_sec) * 1000 + \ | |
95 | ((long)tv_after.tv_usec - (long)tv_before.tv_usec) / 1000) << "real ms." | |
96 | ||
da21dc88 DB |
97 | if (rc == 0) |
98 | { | |
99 | // Save the module, if necessary. | |
100 | if (s.last_pass == 4) | |
101 | s.save_module = true; | |
102 | ||
103 | // Copy module to the current directory. | |
104 | if (! pending_interrupts) | |
105 | { | |
106 | if (s.save_module) | |
107 | { | |
108 | string module_src_path = s.tmpdir + "/" + s.module_filename(); | |
109 | string module_dest_path = s.module_filename(); | |
110 | copy_file (module_src_path, module_dest_path, s.verbose >= 3); | |
111 | // Also copy the module signature, it it exists. | |
112 | module_src_path += ".sgn"; | |
113 | if (file_exists (module_src_path)) | |
114 | { | |
115 | module_dest_path += ".sgn"; | |
116 | copy_file(module_src_path, module_dest_path, s.verbose >= 3); | |
117 | } | |
118 | } | |
119 | // Print the name of the module | |
120 | if (s.last_pass == 4) | |
121 | { | |
122 | cout << s.module_filename() << endl; | |
123 | } | |
124 | } | |
125 | } | |
126 | ||
aa4d21c0 DB |
127 | // syntax errors, if any, are already printed |
128 | if (s.verbose) | |
129 | { | |
a46f9abe FCE |
130 | string ws = s.winning_server; |
131 | if (ws == "") ws = "?"; | |
132 | clog << _("Passes: via server ") << ws << " " | |
85007c04 | 133 | << getmemusage() |
aa4d21c0 DB |
134 | << TIMESPRINT |
135 | << endl; | |
136 | } | |
bba368c5 | 137 | if (rc && !s.dump_mode) |
a46f9abe FCE |
138 | { |
139 | clog << _("Passes: via server failed. Try again with another '-v' option.") << endl; | |
140 | } | |
aa4d21c0 | 141 | |
0f5d597d | 142 | PROBE1(stap, client__end, &s); |
aa4d21c0 DB |
143 | |
144 | return rc; | |
145 | } | |
146 | ||
2fad97fd DB |
147 | // Initialize a client/server session. |
148 | int | |
149 | compile_server_client::initialize () | |
150 | { | |
151 | int rc = 0; | |
152 | ||
2fad97fd DB |
153 | // Create a temporary directory to package things in. |
154 | client_tmpdir = s.tmpdir + "/client"; | |
155 | rc = create_dir (client_tmpdir.c_str ()); | |
156 | if (rc != 0) | |
157 | { | |
158 | const char* e = strerror (errno); | |
aeb9cc10 | 159 | clog << _("ERROR: cannot create temporary directory (\"") |
2fad97fd DB |
160 | << client_tmpdir << "\"): " << e |
161 | << endl; | |
01fb72a0 | 162 | return rc; |
2fad97fd | 163 | } |
01fb72a0 | 164 | backend->set_tmpdir(client_tmpdir); |
2fad97fd | 165 | |
01fb72a0 | 166 | return backend->initialize(); |
2fad97fd DB |
167 | } |
168 | ||
169 | // Create the request package. | |
170 | int | |
171 | compile_server_client::create_request () | |
172 | { | |
cc7c72cd | 173 | // Add the current protocol version. |
01fb72a0 | 174 | int rc = backend->add_protocol_version (CURRENT_CS_PROTOCOL_VERSION); |
cc7c72cd DB |
175 | if (rc != 0) |
176 | return rc; | |
2fad97fd DB |
177 | |
178 | // Add the script file or script option | |
179 | if (s.script_file != "") | |
180 | { | |
181 | if (s.script_file == "-") | |
182 | { | |
183 | // Copy the script from stdin | |
184 | string packaged_script_dir = client_tmpdir + "/script"; | |
185 | rc = create_dir (packaged_script_dir.c_str ()); | |
186 | if (rc != 0) | |
187 | { | |
188 | const char* e = strerror (errno); | |
aeb9cc10 | 189 | clog << _("ERROR: cannot create temporary directory ") |
2fad97fd DB |
190 | << packaged_script_dir << ": " << e |
191 | << endl; | |
192 | return rc; | |
193 | } | |
194 | rc = ! copy_file("/dev/stdin", packaged_script_dir + "/-"); | |
f3fbabf2 DB |
195 | if (rc != 0) |
196 | return rc; | |
2fad97fd | 197 | |
01fb72a0 DS |
198 | // Let the backend know the file is there. |
199 | rc = backend->add_tmpdir_file ("script/-"); | |
200 | if (rc != 0) | |
201 | return rc; | |
202 | ||
203 | // Name the script in the stap cmd arguments. | |
204 | rc = backend->add_cmd_arg ("script/-"); | |
f3fbabf2 DB |
205 | if (rc != 0) |
206 | return rc; | |
2fad97fd DB |
207 | } |
208 | else | |
01fb72a0 DS |
209 | { |
210 | // Add the script. | |
211 | rc = backend->include_file_or_directory ("script", s.script_file); | |
f3fbabf2 DB |
212 | if (rc != 0) |
213 | return rc; | |
2fad97fd DB |
214 | } |
215 | } | |
216 | ||
217 | // Add -I paths. Skip the default directory. | |
218 | if (s.include_arg_start != -1) | |
219 | { | |
220 | unsigned limit = s.include_path.size (); | |
221 | for (unsigned i = s.include_arg_start; i < limit; ++i) | |
222 | { | |
01fb72a0 DS |
223 | rc = backend->include_file_or_directory ("tapset", |
224 | s.include_path[i]); | |
225 | if (rc != 0) | |
226 | return rc; | |
227 | rc = backend->add_cmd_arg ("-I"); | |
f3fbabf2 DB |
228 | if (rc != 0) |
229 | return rc; | |
01fb72a0 | 230 | rc = backend->add_cmd_arg ("tapset"); |
f3fbabf2 DB |
231 | if (rc != 0) |
232 | return rc; | |
2fad97fd DB |
233 | } |
234 | } | |
235 | ||
236 | // Add other options. | |
01fb72a0 | 237 | rc = add_cmd_args (); |
f3fbabf2 DB |
238 | if (rc != 0) |
239 | return rc; | |
2fad97fd | 240 | |
01fb72a0 DS |
241 | // Add the sysinfo. |
242 | rc = backend->add_sysinfo (); | |
e4e3d6b7 CM |
243 | if (rc != 0) |
244 | return rc; | |
245 | ||
246 | // Add localization data | |
247 | rc = add_localization_variables(); | |
2fad97fd | 248 | |
01fb72a0 | 249 | // Add the machine owner key (MOK) fingerprints, if needed. |
cd1418c7 | 250 | if (! s.mok_fingerprints.empty()) |
b3367f63 DS |
251 | { |
252 | ostringstream fingerprints; | |
253 | vector<string>::const_iterator it; | |
cd1418c7 | 254 | for (it = s.mok_fingerprints.begin(); it != s.mok_fingerprints.end(); |
b3367f63 | 255 | it++) |
01fb72a0 DS |
256 | backend->add_mok_fingerprint(*it); |
257 | rc = backend->finalize_mok_fingerprints(); | |
b3367f63 | 258 | if (rc != 0) |
01fb72a0 | 259 | return rc; |
b3367f63 DS |
260 | } |
261 | ||
2fad97fd DB |
262 | return rc; |
263 | } | |
264 | ||
265 | // Add the arguments specified on the command line to the server request | |
266 | // package, as appropriate. | |
f3fbabf2 | 267 | int |
01fb72a0 | 268 | compile_server_client::add_cmd_args () |
2fad97fd | 269 | { |
fd20a70c | 270 | // stap arguments to be passed to the server. |
f3fbabf2 | 271 | int rc = 0; |
2fad97fd DB |
272 | unsigned limit = s.server_args.size(); |
273 | for (unsigned i = 0; i < limit; ++i) | |
f3fbabf2 | 274 | { |
01fb72a0 | 275 | rc = backend->add_cmd_arg (s.server_args[i]); |
f3fbabf2 DB |
276 | if (rc != 0) |
277 | return rc; | |
278 | } | |
fd20a70c DB |
279 | |
280 | // Script arguments. | |
281 | limit = s.args.size(); | |
282 | if (limit > 0) { | |
01fb72a0 | 283 | rc = backend->add_cmd_arg ("--"); |
fd20a70c DB |
284 | if (rc != 0) |
285 | return rc; | |
286 | for (unsigned i = 0; i < limit; ++i) | |
287 | { | |
01fb72a0 | 288 | rc = backend->add_cmd_arg (s.args[i]); |
fd20a70c DB |
289 | if (rc != 0) |
290 | return rc; | |
291 | } | |
292 | } | |
f3fbabf2 | 293 | return rc; |
2fad97fd DB |
294 | } |
295 | ||
e4e3d6b7 CM |
296 | // Add the localization variables to the server request |
297 | // package. | |
298 | int | |
299 | compile_server_client::add_localization_variables() | |
300 | { | |
e4e3d6b7 | 301 | const set<string> &locVars = localization_variables(); |
e4e3d6b7 CM |
302 | |
303 | /* Note: We don't have to check for the contents of the environment | |
304 | * variables here, since they will be checked extensively on the | |
305 | * server. | |
306 | */ | |
01fb72a0 | 307 | for (auto it = locVars.begin(); it != locVars.end(); it++) |
e4e3d6b7 CM |
308 | { |
309 | char* var = getenv((*it).c_str()); | |
310 | if (var) | |
01fb72a0 | 311 | backend->add_localization_variable(*it, var); |
e4e3d6b7 | 312 | } |
01fb72a0 | 313 | return backend->finalize_localization_variables(); |
e4e3d6b7 CM |
314 | } |
315 | ||
2e46c01a | 316 | /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ |