-
Notifications
You must be signed in to change notification settings - Fork 2
/
lib-ts.c
358 lines (319 loc) · 9.72 KB
/
lib-ts.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
/* SPDX-License-Identifier: Apache-2.0 */
/* (c) Copyright 2019 - 2022 Xilinx, Inc. All rights reserved. */
/** @file
* @brief Common lib for SF Tets Suites
*
* Implementation of common functions.
*
* @author Denis Pryazhennikov <Denis.Pryazhennikov@oktetlabs.ru>
*/
#define TE_LGR_USER "Onload Library"
#include "lib-ts.h"
/* See description in lib-ts.h */
te_errno
libts_fix_ta_path_env(const char *ta_name)
{
if (ta_name == NULL)
{
ERROR("%s(): wrong argument value", __FUNCTION__);
return TE_EINVAL;
}
return tapi_sh_env_ta_path_append(ta_name, "/sbin:/usr/sbin");
}
/* See description in lib-ts.h */
void
libts_fix_tas_path_env(void)
{
unsigned int nb_ta_handles;
cfg_handle *ta_handles;
char *ta_name = NULL;
unsigned int i;
CHECK_RC(cfg_find_pattern_fmt(&nb_ta_handles, &ta_handles, "/agent:*"));
for (i = 0; i < nb_ta_handles; i++)
{
CHECK_RC(cfg_get_inst_name(ta_handles[i], &ta_name));
CHECK_RC(libts_fix_ta_path_env(ta_name));
free(ta_name);
}
free(ta_handles);
}
/* See description in lib-ts.h */
void
libts_set_zf_host_addr(void)
{
te_string zf_attr = TE_STRING_INIT_STATIC(RCF_MAX_PATH);
cfg_handle *addresses = NULL;
char *inst_name = NULL;
const char *if_name = NULL;
const char *ta = NULL;
unsigned int addr_num;
cfg_handle handle = CFG_HANDLE_INVALID;
te_errno rc;
te_bool ip4_found = FALSE;
unsigned int i;
if ((ta = getenv("TE_IUT_TA_NAME_NS")) == NULL)
return;
if ((if_name = getenv("TE_IUT_TST1")) == NULL)
return;
rc = cfg_find_fmt(&handle, "/local:%s/env:ZF_ATTR", ta);
if (TE_RC_GET_ERROR(rc) == TE_ENOENT)
return;
CHECK_RC(cfg_get_instance(handle, NULL, &inst_name));
CHECK_RC(te_string_append(&zf_attr, "%s", inst_name));
free(inst_name);
CHECK_RC(cfg_find_pattern_fmt(&addr_num, &addresses,
"/agent:%s/interface:%s/net_addr:*",
ta, if_name));
for (i = 0; i < addr_num; i++)
{
CHECK_RC(cfg_get_inst_name(addresses[i], &inst_name));
/* Checking for version ip address. IPv4 is needed for ZF. */
if (strchr(inst_name, ':') == NULL)
{
ip4_found = TRUE;
break;
}
free(inst_name);
}
if (ip4_found == FALSE)
{
ERROR("Failed to find IPv4 address of %s", if_name);
return;
}
CHECK_RC(te_string_append(&zf_attr, ";zfss_implicit_host=%s", inst_name));
CHECK_RC(cfg_set_instance(handle, CVT_STRING, zf_attr.ptr));
free(inst_name);
free(addresses);
}
/* See description in lib-ts.h */
void
libts_init_console_loglevel(void)
{
/* We reset IUT console loglevel to 7 by default.
* See ST-1706: Test debug kernels with the Socket Tester
* for explanation. */
#define DEFAULT_LOGLEVEL 7
const char *level_str = getenv("ST_CONSOLE_LOGLEVEL");
long level = DEFAULT_LOGLEVEL;
/*
* --script=ool.console_loglevel: without a number means
* "do not change the logvelel"
* */
if (level_str != NULL && level_str[0] == '\0')
return;
if (level_str != NULL && level_str[0] != '\0')
{
level = strtol(level_str, NULL, 0);
if( level < 0 || level > 15 )
{
WARN("Unparseable value of ST_CONSOLE_LOGLEVEL: \"%s\", "
"using %d", level_str, DEFAULT_LOGLEVEL);
level = DEFAULT_LOGLEVEL;
}
}
tapi_cfg_set_loglevel_save(getenv("TE_IUT_TA_NAME"), level, NULL);
}
/* See description in lib-ts.h */
void
libts_send_enter2serial_console(const char *ta,
const char *rpc_server_name,
const char *console_name)
{
rcf_rpc_server *rpcs_serial;
tapi_serial_handle p_handle = NULL;
char *te_sc_write_disable = getenv("TE_SERIAL_CONSOLE_WRITE_DISABLE");
if (te_sc_write_disable != NULL && te_sc_write_disable[0] != '\0')
{
RING("%s() is disabled by TE_SERIAL_CONSOLE_WRITE_DISABLE",
__FUNCTION__);
return;
}
/* It fails when Agt_D doesn't exist. */
if (rcf_rpc_server_create(ta, rpc_server_name,
&rpcs_serial) != 0)
{
WARN("Failed to create RPC server on %s", ta);
return;
}
RPC_AWAIT_IUT_ERROR(rpcs_serial);
tapi_serial_open_rpcs(rpcs_serial, console_name,
&p_handle);
if (p_handle != NULL && p_handle->sock > 0)
{
CHECK_RC(tapi_serial_force_rw(p_handle));
CHECK_RC(tapi_serial_send_enter(p_handle));
CHECK_RC(tapi_serial_spy(p_handle));
}
else
{
WARN("Failed to open console for %s", ta);
}
CHECK_RC(rcf_rpc_server_destroy(rpcs_serial));
}
/* See description in lib-ts.h */
int
libts_file_copy_ta(const char *ta, const char *src, const char *dst,
te_bool non_exist_f)
{
int rc;
if (src != NULL && strncmp(src, "iut:", sizeof("iut:") - 1) == 0)
{
rc = tapi_file_copy_ta(ta, &src[sizeof("iut:") - 1], ta, dst);
if (rc != 0)
{
ERROR("Failed to copy file '%s' to %s on agent %s",
src, dst, ta);
if (!non_exist_f)
return 0;
}
else
{
RING("File '%s' copied to %s on agent %s", src, dst, ta);
}
}
else
{
if ((rc = access(src, F_OK)) < 0)
{
ERROR("There is no such tool or library in gnu build: %s",
src);
if (!non_exist_f)
return 0;
else
return rc;
}
rc = rcf_ta_put_file(ta, 0, src, dst);
if (rc != 0)
{
ERROR("Failed to put file '%s' to %s:%s", src, ta, dst);
}
else
{
RING("File '%s' put to %s:%s", src, ta, dst);
}
}
return rc;
}
/* See description in lib-ts.h */
te_errno
libts_copy_socklibs(void)
{
te_errno rc;
unsigned int n_socklibs;
cfg_handle *socklibs = NULL;
unsigned int i;
cfg_val_type val_type;
cfg_oid *oid = NULL;
rc = cfg_find_pattern("/local:*/socklib:", &n_socklibs, &socklibs);
if (rc != 0)
{
TEST_FAIL("cfg_find_pattern(/local:*/socklib:) failed: %r", rc);
}
for (i = 0; i < n_socklibs; ++i)
{
const char * const libdir_def = "/usr/lib";
const char * const remote_libname = "libte-iut.so";
char *socklib;
char *libdir;
char *remote_file;
val_type = CVT_STRING;
rc = cfg_get_instance(socklibs[i], &val_type, &socklib);
if (rc != 0)
{
free(socklibs);
TEST_FAIL("cfg_get_instance() failed: %r", rc);
}
if (strlen(socklib) == 0)
{
/* Just ignore empty values */
free(socklib);
continue;
}
rc = cfg_get_oid(socklibs[i], &oid);
if (rc != 0)
{
free(socklib);
free(socklibs);
TEST_FAIL("cfg_get_oid() failed: %r", rc);
}
val_type = CVT_STRING;
rc = cfg_get_instance_fmt(&val_type, &libdir,
"/local:%s/libdir:",
CFG_OID_GET_INST_NAME(oid, 1));
if (rc == TE_RC(TE_CS, TE_ENOENT))
{
libdir = (char *)libdir_def;
}
else if (rc != 0)
{
cfg_free_oid(oid);
free(socklib);
free(socklibs);
TEST_FAIL("%u: cfg_get_instance_fmt() failed", __LINE__);
}
/* Prepare name of the remote file to put */
remote_file = malloc(strlen(libdir) + 1 /* '/' */ +
strlen(remote_libname) + 1 /* '\0' */);
if (remote_file == NULL)
{
if (libdir != libdir_def)
free(libdir);
cfg_free_oid(oid);
free(socklib);
free(socklibs);
TEST_FAIL("Memory allocation failure");
}
strcpy(remote_file, libdir);
if (libdir != libdir_def)
free(libdir);
strcat(remote_file, "/");
strcat(remote_file, remote_libname);
rc = libts_file_copy_ta(CFG_OID_GET_INST_NAME(oid, 1), socklib,
remote_file, TRUE);
if (rc != 0)
{
free(remote_file);
cfg_free_oid(oid);
free(socklib);
free(socklibs);
goto cleanup;
}
free(socklib);
rc = cfg_set_instance(socklibs[i], val_type, remote_file);
if (rc != 0)
{
free(remote_file);
cfg_free_oid(oid);
free(socklibs);
TEST_FAIL("cfg_set_instance() failed: %r", rc);
}
{
int rc2;
rc = rcf_ta_call(CFG_OID_GET_INST_NAME(oid, 1), 0, "shell",
&rc2, 3, TRUE, "chmod", "+s,a+rx", remote_file);
if (rc != 0)
{
ERROR("Failed to call 'shell' on %s: %r",
CFG_OID_GET_INST_NAME(oid, 1), rc);
free(remote_file);
cfg_free_oid(oid);
free(socklibs);
goto cleanup;
}
if ((rc = rc2) != 0)
{
ERROR("Failed to execute 'chmod' on %s: %r",
CFG_OID_GET_INST_NAME(oid, 1), rc2);
free(remote_file);
cfg_free_oid(oid);
free(socklibs);
goto cleanup;
}
}
free(remote_file);
cfg_free_oid(oid);
}
free(socklibs);
cleanup:
return rc;
}