@cryptotaxi247 / netdata-1 / commits / 3e806abc2

eBPF plugin remove parallel plugins (#11287)

Add helpers to avoid multiple plugins running in parallel

thiagoftsm committed Jun 30, 2021 at 12:05 UTC 3e806abc296cae047fd3cba414044e43486e1967
1 file changed +131
collectors/ebpf.plugin/ebpf.c
+131
@@ -1242,6 +1242,136 @@ static void parse_args(int argc, char **argv)
1242 *
1243 *****************************************************************/
1244
1245 +/**
1246 + * Update PID file
1247 + *
1248 + * Update the content of PID file
1249 + *
1250 + * @param filename is the full name of the file.
1251 + * @param pid that identifies the process
1252 + */
1253 +static void ebpf_update_pid_file(char *filename, pid_t pid)
1254 +{
1255 + FILE *fp = fopen(filename, "w");
1256 + if (!fp)
1257 + return;
1258 +
1259 + fprintf(fp, "%d", pid);
1260 + fclose(fp);
1261 +}
1262 +
1263 +/**
1264 + * Get Process Name
1265 + *
1266 + * Get process name from /proc/PID/status
1267 + *
1268 + * @param pid that identifies the process
1269 + */
1270 +static char *ebpf_get_process_name(pid_t pid)
1271 +{
1272 + char *name = NULL;
1273 + char filename[FILENAME_MAX + 1];
1274 + snprintfz(filename, FILENAME_MAX, "/proc/%d/status", pid);
1275 +
1276 + procfile *ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT);
1277 + if(unlikely(!ff)) {
1278 + error("Cannot open %s", filename);
1279 + return name;
1280 + }
1281 +
1282 + ff = procfile_readall(ff);
1283 + if(unlikely(!ff))
1284 + return name;
1285 +
1286 + unsigned long i, lines = procfile_lines(ff);
1287 + for(i = 0; i < lines ; i++) {
1288 + char *cmp = procfile_lineword(ff, i, 0);
1289 + if (!strcmp(cmp, "Name:")) {
1290 + name = strdupz(procfile_lineword(ff, i, 1));
1291 + break;
1292 + }
1293 + }
1294 +
1295 + procfile_close(ff);
1296 +
1297 + return name;
1298 +}
1299 +
1300 +/**
1301 + * Read Previous PID
1302 + *
1303 + * @param filename is the full name of the file.
1304 + *
1305 + * @return It returns the PID used during previous execution on success or 0 otherwise
1306 + */
1307 +static pid_t ebpf_read_previous_pid(char *filename)
1308 +{
1309 + FILE *fp = fopen(filename, "r");
1310 + if (!fp)
1311 + return 0;
1312 +
1313 + char buffer[64];
1314 + size_t length = fread(buffer, sizeof(*buffer), 63, fp);
1315 + pid_t old_pid = 0;
1316 + if (length) {
1317 + if (length > 63)
1318 + length = 63;
1319 +
1320 + buffer[length] = '\0';
1321 + old_pid = (pid_t)str2uint32_t(buffer);
1322 + }
1323 + fclose(fp);
1324 +
1325 + return old_pid;
1326 +}
1327 +
1328 +/**
1329 + * Kill previous process
1330 + *
1331 + * Kill previous process whether it was not closed.
1332 + *
1333 + * @param filename is the full name of the file.
1334 + * @param pid that identifies the process
1335 + */
1336 +static void ebpf_kill_previous_process(char *filename, pid_t pid)
1337 +{
1338 + pid_t old_pid = ebpf_read_previous_pid(filename);
1339 + if (!old_pid)
1340 + return;
1341 +
1342 + // Process is not running
1343 + char *prev_name = ebpf_get_process_name(old_pid);
1344 + if (!prev_name)
1345 + return;
1346 +
1347 + char *current_name = ebpf_get_process_name(pid);
1348 +
1349 + if (!strcmp(prev_name, current_name))
1350 + kill(old_pid, SIGKILL);
1351 +
1352 + freez(prev_name);
1353 + freez(current_name);
1354 +
1355 + // wait few microseconds before start new plugin
1356 + sleep_usec(USEC_PER_MS * 300);
1357 +}
1358 +
1359 +/**
1360 + * Manage PID
1361 + *
1362 + * This function kills another instance of eBPF whether it is necessary and update the file content.
1363 + *
1364 + * @param pid that identifies the process
1365 + */
1366 +static void ebpf_manage_pid(pid_t pid)
1367 +{
1368 + char filename[FILENAME_MAX + 1];
1369 + snprintfz(filename, FILENAME_MAX, "%s%s/ebpf.d/ebpf.pid", netdata_configured_host_prefix, ebpf_plugin_dir);
1370 +
1371 + ebpf_kill_previous_process(filename, pid);
1372 + ebpf_update_pid_file(filename, pid);
1373 +}
1374 +
1375 /**
1376 * Load collector config
1377 *
@@ -1268,6 +1398,7 @@ int main(int argc, char **argv)
1398 set_global_variables();
1399 parse_args(argc, argv);
1400 ebpf_load_thread_config();
1401 + ebpf_manage_pid(getpid());
1402
1403 running_on_kernel = get_kernel_version(kernel_string, 63);
1404 if (!has_condition_to_run(running_on_kernel)) {