|
19 | 19 | #include <errno.h> |
20 | 20 | #include <unistd.h> |
21 | 21 | #include <dirent.h> |
| 22 | +#include <dlfcn.h> |
22 | 23 | #include <grp.h> |
23 | 24 | #include <string.h> |
24 | 25 | #include <sys/time.h> |
25 | 26 | #include <sys/resource.h> |
| 27 | +#include <sys/mman.h> |
| 28 | +#include <fcntl.h> |
| 29 | + |
26 | 30 |
|
27 | 31 | #include "crm/crm.h" |
28 | 32 | #include "crm/common/mainloop.h" |
@@ -1174,6 +1178,10 @@ services__execute_file(svc_action_t *op) |
1174 | 1178 | struct stat st; |
1175 | 1179 | struct sigchld_data_s data; |
1176 | 1180 |
|
| 1181 | + if (services__execute_file_as_plugin(op) == pcmk_rc_ok){ |
| 1182 | + return pcmk_rc_ok; |
| 1183 | + } |
| 1184 | + |
1177 | 1185 | // Catch common failure conditions early |
1178 | 1186 | if (stat(op->opaque->exec, &st) != 0) { |
1179 | 1187 | rc = errno; |
@@ -1436,3 +1444,102 @@ services_os_get_directory_list(const char *root, gboolean files, gboolean execut |
1436 | 1444 |
|
1437 | 1445 | return result; |
1438 | 1446 | } |
| 1447 | + |
| 1448 | +int |
| 1449 | +services__execute_file_as_plugin(svc_action_t *op) { |
| 1450 | + void *handle; |
| 1451 | + int (*exec)(int, int, char *); |
| 1452 | + char *lib_error; |
| 1453 | + int exec_status; |
| 1454 | + char dst[200] = "/usr/lib/ocf/resource.d/heartbeat/"; |
| 1455 | + strcat(dst, op->agent); |
| 1456 | + handle = dlopen (dst, RTLD_NOW | RTLD_LOCAL); |
| 1457 | + |
| 1458 | + if (!handle) { |
| 1459 | + // можно что-то залогировать |
| 1460 | + return pcmk_rc_error; |
| 1461 | + } else { |
| 1462 | + // можно что-то залогировать |
| 1463 | + exec = dlsym(handle, "handler"); |
| 1464 | + |
| 1465 | + if ((lib_error = dlerror()) != NULL){ |
| 1466 | + free(lib_error); |
| 1467 | + |
| 1468 | + // можно что-то залогировать |
| 1469 | + // ситуация, когда мы смогли открыть агента |
| 1470 | + // как разделяемую библиотеку, но не нашли |
| 1471 | + // нужного метода (что-то странное) |
| 1472 | + return pcmk_rc_error; |
| 1473 | + } else { |
| 1474 | + char num[10]; |
| 1475 | + int out_fd; |
| 1476 | + int err_fd; |
| 1477 | + char out_file_name[100] = "outfd-"; |
| 1478 | + char err_file_name[100] = "errfd-"; |
| 1479 | + |
| 1480 | + add_action_env_vars(op); |
| 1481 | + |
| 1482 | + sprintf(num, "%d", getpid()); |
| 1483 | + strcat(out_file_name, num); |
| 1484 | + strcat(err_file_name, num); |
| 1485 | + |
| 1486 | + out_fd = memfd_create(out_file_name, MFD_ALLOW_SEALING); |
| 1487 | + err_fd = memfd_create(err_file_name, MFD_ALLOW_SEALING); |
| 1488 | + |
| 1489 | + exec_status = exec(out_fd, err_fd, op->action); |
| 1490 | + { |
| 1491 | + int size_out = lseek(out_fd, 0, SEEK_END); // SEEK_CUR ? |
| 1492 | + int size_err = lseek(err_fd, 0, SEEK_END); |
| 1493 | + if (size_out > 0) { |
| 1494 | + char *buf_out = (char *)malloc(sizeof(char) * (size_out + 1)); |
| 1495 | + lseek(out_fd, 0, SEEK_SET); |
| 1496 | + if (read(out_fd, buf_out, size_out) >= 0) { |
| 1497 | + buf_out[size_out] = '\0'; |
| 1498 | + op->stdout_data = buf_out; |
| 1499 | + } |
| 1500 | + } else { |
| 1501 | + op->stdout_data = NULL; |
| 1502 | + } |
| 1503 | + |
| 1504 | + if (size_err > 0) { |
| 1505 | + char *buf_err = (char *)malloc(sizeof(char) * (size_err + 1)); |
| 1506 | + lseek(err_fd, 0, SEEK_SET); |
| 1507 | + if (read(err_fd, buf_err, size_err) >= 0) { |
| 1508 | + buf_err[size_err] = '\0'; |
| 1509 | + op->stderr_data = buf_err; |
| 1510 | + } |
| 1511 | + } else { |
| 1512 | + op->stderr_data = NULL; |
| 1513 | + } |
| 1514 | + |
| 1515 | + if (close(out_fd) < 0) { |
| 1516 | + crm_info("Error '%s'", "a"); |
| 1517 | + } |
| 1518 | + if (close(err_fd) < 0) { |
| 1519 | + crm_info("Error 's'", "b"); |
| 1520 | + } |
| 1521 | + |
| 1522 | + op->rc = exec_status; |
| 1523 | + op->status = PCMK_EXEC_DONE; |
| 1524 | + op->pid = 0; |
| 1525 | + if (op->interval_ms != 0) { |
| 1526 | + // Recurring operations must be either cancelled or rescheduled |
| 1527 | + if (op->cancel) { |
| 1528 | + services__set_cancelled(op); |
| 1529 | + cancel_recurring_action(op); |
| 1530 | + } else { |
| 1531 | + op->opaque->repeat_timer = g_timeout_add(op->interval_ms, |
| 1532 | + recurring_action_timer, |
| 1533 | + (void *) op); |
| 1534 | + } |
| 1535 | + } |
| 1536 | + if (op->opaque->callback) { |
| 1537 | + op->opaque->callback(op); |
| 1538 | + } |
| 1539 | + } |
| 1540 | + dlclose(handle); |
| 1541 | + return pcmk_rc_ok; |
| 1542 | + //dlclose(handle); |
| 1543 | + } |
| 1544 | + } |
| 1545 | +} |
0 commit comments