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)) {