import worker code

This commit is contained in:
Rongsong Shen 2025-11-24 15:53:31 +08:00
parent 61654a06e8
commit 8831040043
64 changed files with 20853 additions and 1 deletions

View file

@ -0,0 +1,29 @@
/* 此模块为预留功能,它提供了xcecd处理远程连接的可能。xcecd默认会打开一个监听端口并能接受外部请求。
* 此保留功能是为了提供LSF兼容性,默认不使能。
*/
#ifndef CONNECTION_HANDLER_H
#define CONNECTION_HANDLER_H
#include <stdint.h>
typedef struct network_handler network_handler_t;
// 网络请求回调函数类型
typedef const char* (*request_handler_t)(const char* request, void* user_data);
// 创建网络处理器
network_handler_t* network_handler_create(uint16_t port);
// 设置请求处理回调
void network_handler_set_callback(network_handler_t* handler, request_handler_t callback, void* user_data);
// 启动网络监听
int network_handler_start(network_handler_t* handler);
// 停止网络监听
void network_handler_stop(network_handler_t* handler);
// 销毁网络处理器
void network_handler_destroy(network_handler_t* handler);
#endif // CONNECTION_HANDLER_H

View file

@ -0,0 +1,62 @@
#ifndef CONTROL_CONNECTOR_H
#define CONTROL_CONNECTOR_H
#include "thread_pool.h"
#include "xcecd_utils.h"
#include "client.h"
#include "xcectx.h"
#include "controller.capnp.h"
typedef struct {
xce_client_config_t* conf;
endpoint_t ep;
xce_ctx_t ctx;
} api_ctx_t;
typedef struct controller_connector_ctx_s {
void *thread_pool;
void *process_manager;
char *remote_host;
char *virtual_name;
void **worker_list;
int remote_port;
int join_interval;
bool running;
} controller_connector_ctx_t;
extern controller_connector_ctx_t *cc_ctx;
typedef struct {
int (*job_finished)(xcecd_job_t *job);
int (*job_stopped)(uint64_t jobid);
int (*job_resumed)(uint64_t jobid);
int (*job_start_error)(uint64_t jobid);
int (*job_status_error)(uint64_t jobid);
int (*job_ckpted)(uint64_t jobid, int status, const char *info);
int (*job_remote_start)(uint64_t jobid, const char *hostname, const char *command);
bool (*reply_startjob)(xcecd_job_t *job);
} cc_callbacks_t;
extern void xcecd_process_command(void* arg);
int start_controller_connector_thread(task_func_t function, void* arg);
int xcecd_join_cluster(hostattrs_t* attrs);
bool controller_connector_start(void);
bool xcecd_reply_startjob(xcecd_job_t *job);
int xcecd_job_finished(xcecd_job_t *job);
int xcecd_job_stopped(uint64_t jobid);
int xcecd_job_resumed(uint64_t jobid);
int checking_connection();
int xcecd_job_start_error(uint64_t jobid);
int xcecd_job_status_error(uint64_t jobid);
int xcecd_job_ckpted(uint64_t jobid, int status, const char *info);
int xcecd_job_remote_start(uint64_t jobid,
const char *hostname,
const char *command);
const cc_callbacks_t* get_cc_callbacks(void);
int xcecd_task_fail(uint64_t jobid, int clientidx,
int taskidx, int code);
int xcecd_jobpost_done(uint64_t jobid);
int xcecd_notify_job_fail(uint64_t jobid,
int stage,
int code);
#endif // CONTROL_CONNECTOR_H

View file

@ -0,0 +1,28 @@
#ifndef HARDWARE_MONITOR_H
#define HARDWARE_MONITOR_H
#include <stdbool.h>
#include <sys/types.h>
#include <time.h>
typedef struct hardware_monitor hardware_monitor_t;
// 创建硬件监控器
hardware_monitor_t* hardware_monitor_create(const char* acct_file);
// 销毁硬件监控器
void hardware_monitor_destroy(hardware_monitor_t* monitor);
// 更新硬件信息
bool hardware_monitor_update(hardware_monitor_t* monitor);
// 获取CPU核心数
int hardware_monitor_get_cpu_cores(hardware_monitor_t* monitor);
double hardware_monitor_get_total_memory(hardware_monitor_t* monitor);
double hardware_monitor_get_free_memory(hardware_monitor_t* monitor);
bool hardware_monitor_get_memory_info(int64_t* total_memory, int64_t* free_memory);
#endif // HARDWARE_MONITOR_H

View file

@ -0,0 +1,23 @@
#ifndef _INTER_JOB_UTILS_H
#define _INTER_JOB_UTILS_H
#define CMD_MAX_LENGTH 4096
#define URL_MAX_LENGTH 256
#define TTY_END_PORT 10000
#define XJOB_END_PORT 5999
typedef struct {
int tty_port;
int xjob_port;
} port_info_t;
int check_port_availability(int port_number);
int find_available_port(int start_port, int end_port);
int check_port(port_info_t port, int interactive_mode);
char* generate_cmd(char* job_cmd, port_info_t port, int interactive_mode);
char* generate_url(port_info_t port, int interactive_mode);
int export_display_env(int port);
#endif /* _INTER_JOB_UTILS_H */

View file

@ -0,0 +1,211 @@
#ifndef JOB_INFORMATION_H
#define JOB_INFORMATION_H
#include "xcecd_utils.h"
#include <sys/types.h>
#include <netinet/in.h>
#define NBUILTINDEX 11
#define MAX_LSB_NAME_LEN 60
#define MAXFILENAMELEN 256
struct job_specs {
char *job_name;
char *job_owner;
char *job_group;
char *job_project;
char *job_class;
char *job_type;
char *job_queue;
char *job_start_time;
char *job_end_time;
char *job_window;
char *job_flags;
char *job_exec_host;
char *job_exec_port;
char *job_exec_path;
char *job_exec_args;
char *job_exec_env;
char *job_exec_dir;
char *job_exec_user;
char *job_exec_group;
char *job_exec_shell;
char *job_exec_type;
char *job_exec_flags;
char *job_exec_window;
char *job_exec_start_time;
char *job_exec_end_time;
char *job_exec_queue;
char *job_exec_project;
char *job_exec_class;
};
struct xce_rusage {
float ru_utime;
float ru_stime;
float ru_maxrss;
float ru_ixrss;
float ru_idrss;
float ru_isrss;
float ru_minflt;
float ru_majflt;
float ru_nswap;
float ru_inblock;
float ru_oublock;
float ru_msgsnd;
float ru_msgrcv;
float ru_nsignals;
float ru_nvcsw;
float ru_nivcsw;
};
struct job_rusage {
float cpu_time;
float max_rss;
float ixrss;
float idrss;
float isrss;
float minflt;
float majflt;
float nswap;
float inblock;
float oublock;
float msgsnd;
float msgrcv;
float nsignals;
float nvcsw;
float nivcsw;
};
struct res_val {
char *selectStr;
int nphase;
int order[NBUILTINDEX];
int genClass;
float *val;
int nindex;
int *indicies;
int *rusgBitMaps;
int duration;
float decay;
int numHosts;
int maxNumHosts;
int pTile;
int options;
int selectStrSize;
char **xorExprs;
};
// 以上结构体定义为了方便前期调试,后续可能会根据实际情况进行修改,或者从新定义在控制模块中.
// 它们包含 job_specs、xce_rusage、job_rusage、res_val 四个结构体,分别用于作业规格、资源使用情况、作业资源使用情况、资源值的定义
struct client_node {
struct client_node *prev;
struct client_node *next;
int chanfd;
struct sockaddr_in from;
int job_type;
long job_id; // 作业ID,暂定为长整型,后续可能会修改
struct job_card *jp;
};
struct job_card {
struct job_card *next;
struct job_card *prev;
gid_t exec_gid; // 执行用户组ID
char exec_user_name[MAX_LSB_NAME_LEN]; // 执行用户名
int not_reported;
time_t wind_edge; // 时间窗口边界
windows_t *week[8]; // 一周的时间窗口
char active;
char time_expire;
char missing;
char controller_restarted;
time_t wind_warn_time;
int runtime;
int w_status;
/* pre-exec report flag */
float cpu_time;
time_t last_chkpnt_time;
int mig_count;
struct job_specs job_specs;
struct xce_rusage xce_rusage;
int need_report_rusage;
int cleanup_pid;
int collected_child;
int exec_job_flag;
#define JOB_EXEC_QPRE_OK 0x1
#define JOB_EXEC_QPRE_KNOWN 0x2
#define JOB_EXEC_STARTED 0x4
char *stdin_file; // 标准输入文件
time_t last_controller_time; // 最后一次和控制器连接上的时间
struct job_rusage run_rusage; // 运行时资源使用情况
struct job_rusage alloc_rusage; // 控制器资源分配情况
struct job_rusage max_rusage; // 最大资源使用情况
int delievered_message_id;
struct client_node *client;
int reg_op_flag;
struct job_rusage work_rusage;
int job_sup_status;
#define REG_CHKPNT 0x1
#define REG_SIGNAL 0x2
#define REG_RUSAGE 0x4
#define REG_NICE 0x8
struct res_val *resume_cond_val;
struct res_val *stop_cond_val;
int act_flags;
int act_status;
int act_reasons;
int act_sub_reasons;
int exit_pid;
int job_done;
time_t last_check;
char *act_cmd;
char *exit_file;
char *cluster_name;
int server_socket;
int cross_platforms;
char *spooled_exec;
char post_job_started;
char user_job_succeed;
};
struct job_setup {
long job_id;
int job_status;
float cpu_time;
int w_status;
struct xce_rusage xce_rusage;
int reason;
int job_pid;
int job_pgid;
int exec_gid;
int exec_uid;
char exec_user_name[MAX_LSB_NAME_LEN];
char exec_home[MAXFILENAMELEN];
char exec_cwd[MAXFILENAMELEN];
int exec_job_flag;
#define LSB_PRE_ABORT 99
};
void init_job_setup(struct job_setup* setup, const char* data);
void init_job_card(struct job_card* card, const char* data);
int update_job_card(struct job_card* card, const char* data);
void cleanup_job_card(struct job_card* card);
struct client_node* init_client_node(long id);
#endif // JOB_INFORMATION_H

View file

@ -0,0 +1,117 @@
#ifndef NODE_INFORMATION_H_
#define NODE_INFORMATION_H_
#include <stdint.h>
#include <arpa/inet.h>
#include "xcecd_utils.h"
#include "connection_handler.h"
#include "process_manager.h"
#include "system_monitor.h"
#include "hardware_monitor.h"
#include "thread_pool.h"
#define MAXXCENAMELEN 40
#define MAXNODENAMELEN 256
#define MAXCANDHOSTS 10
#define DEFAULT_AFTER_HOUR "19:00-7:00 5:19:00-1:7:00"
struct time_window {
char *window_name; // 窗口名称
windows_t *week[8];
time_t window_edge;
};
struct node_status {
short node_id; // 节点ID
int max_cpu_cores; // CPU核心数
int max_memory; // 内存大小
int num_disk; // 磁盘数量
int max_swap; // 交换空间大小
int max_network; // 网络带宽
unsigned short port_number; // 端口号
char node_type[MAXXCENAMELEN]; // 节点类型
char node_arch[MAXXCENAMELEN]; // 节点架构
};
typedef struct host_node host_node_t;
struct host_node {
char *node_name; // 节点名称
short node_number; // 节点编号
short node_model_number; // 节点型号编号
short node_type_number; // 节点类型编号
in_addr_t *node_ip; // 节点IP地址
struct node_status node_status; // 节点状态
char info_valid; // 信息是否有效
unsigned char protocol_version; // 协议版本
short available_high; // 高可用性
short available_low; // 低可用性
short use; // 使用情况
char *windows; // 时间窗口
windows_t *week[8]; // 一周的时间窗口
time_t window_edge; // 时间窗口边界
time_t last_jack_time; // 最后一次插入时间
int node_inactivity_count; // 节点不活动计数
int *status; // 状态
float *busy_threshold; // 繁忙阈值
float *load_index; // 负载指数
float *user_load_index; // 用户负载指数
int info_mask; // 信息掩码
int load_mask; // 负载掩码
int *resource_bitmap; // 资源位图
int *dynamic_resource_bitmap; // 动态资源位图
int number_of_instances; // 实例数量
host_node_t *next; // 下一个节点
time_t expire_time; // 过期时间
uint8_t migrant;
};
struct cluster_node {
short cluster_number; // 集群编号
char *cluster_name; // 集群名称
int status; // 状态
in_addr_t candidate_address_list[MAXCANDHOSTS]; // 候选地址列表
char *primary_node_name; // 主节点名称
unsigned short primary_address; // 主地址
unsigned short primary_port; // 主端口
char primary_known; // 主节点可识别
int primary_inactivity_count; // 主节点不活动计数
host_node_t *primary_pointer; // 主节点指针
host_node_t *previous_primary_pointer; // 上一个主节点指针
unsigned short checksum; // 校验和
int number_of_nodes; // 节点数量
int number_of_clients; // 客户端数量
host_node_t *node_list; // 节点列表
host_node_t *client_list; // 客户端列表
int manager_id; // 管理器ID
char *manager_name; // 管理器名称
int channel_fd; // 通道文件描述符
int number_of_index; // 索引数量
int number_of_user_index; // 用户索引数量
int user_index_class; // 用户索引类
char **load_index_names; // 负载指数名称
int number_of_admins; // 管理员数量
int *admin_ids; // 管理员ID
char **admin_names; // 管理员名称
int number_of_resouces; // 资源数量
int *resource_bitmaps; // 资源位图
int *hosttype_bitmaps; // 主机类型位图
int *hostmodel_bitmaps; // 主机模型位图
int number_of_shared_resources; // 共享资源数量
char **shared_resources; // 共享资源
struct cluster_node *next;
};
// client_node 和 minSLimConfData 数据结构需要添加吗?
host_node_t* host_node_create(void);
int host_node_update(host_node_t* node_ptr, host_node_t* new_node);
void free_host_node(host_node_t* node_ptr);
int get_cpu_usage(int total_cores, int used_cores);
#endif // NODE_INFORMATION_H_

View file

@ -0,0 +1,128 @@
#ifndef PROCESS_MANAGER_H
#define PROCESS_MANAGER_H
#include <stddef.h>
#include <stdbool.h>
#ifdef _WIN32
#include <windows.h>
typedef HANDLE process_handle_t;
#else
#include <pthread.h>
#include <unistd.h>
typedef pid_t process_handle_t;
#endif
#include "sqlite3.h"
typedef struct {
process_handle_t handle;
char* command; // command line
char* work_dir; // working directory
int status; // process status (0: stopped, 1: running)
int exit_code; // exit code
int output_fd; // output file descriptor
char* log_file; // log file path
#ifdef _WIN32
HANDLE pipe_read; // pipe read handle
HANDLE monitor_thread; // monitor thread handle
bool monitor_active; // monitor thread active flag
#endif
} process_info_t;
typedef struct process_manager {
process_info_t* processes;
size_t process_count;
int update_interval;
bool running;
bool initialized;
#ifdef _WIN32
HANDLE thread;
CRITICAL_SECTION lock;
#else
pthread_t thread;
pthread_mutex_t lock;
#endif
} process_manager_t;
/**
* @brief initialize process info structure
* @param proc process info structure
* @return void
*/
void process_info_init(process_info_t* proc);
/**
* @brief initialize process info structure
* @return process_manager_t* if success, NULL if failed
*/
process_manager_t* process_manager_create(void);
/**
* @brief start a new process
* @param manager process manager without resource limits
* @param command command with arguments
* @return 0 if success, -1 if failed
*/
int process_manager_start_process(process_manager_t* manager, const char* command);
/**
* @brief get the number of processes
* @param manager process manager
* @return the number of processes
*/
int get_process_count(process_manager_t* manager);
/**
* @brief get the current process pid
* @param manager process manager
* @return the current process pid
*/
int get_current_process_pid(process_manager_t* manager);
/**
* @brief update the process status in the list
* @param manager process manager
* @return true if success, false if failed
*/
bool process_manager_update(process_manager_t* manager);
/**
* @brief get process info by handle
* @param manager process manager
* @param handle process handle
* @return process_info_t* if success, NULL if failed
*/
process_info_t* process_manager_get_process_info(process_manager_t* manager, process_handle_t handle);
/**
* @brief terminate a process
* @param manager process manager
* @param handle process handle
* @return 0 if success, -1 if failed
*/
int process_manager_terminate_process(process_manager_t* manager, process_handle_t handle);
/**
* @brief destroy process manager
* @param manager process manager
* @return void
*/
void process_manager_destroy(process_manager_t* manager);
/**
* @brief remove a process from the list
* @param manager process manager
* @param handle process handle
* @return 0 if success, -1 if failed
*/
int process_manager_remove_process(process_manager_t* manager, process_handle_t handle);
/**
* @brief free process manager
* @param manager process manager
* @return void
*/
void process_manager_free(process_manager_t* manager);
#endif // PROCESS_MANAGER_H

View file

@ -0,0 +1,35 @@
/**
* @file process_worker_manager.h
* @brief This file contains the declaration of the worker process manager functions.
* It uses to manage worker process with resource limits. And it relies on
* process_manager.h to manage the worker process. This module disabled by default.
*/
#ifndef _PROCESS_WORKER_MANAGER_H_
#define _PROCESS_WORKER_MANAGER_H_
#include "process_manager.h"
#include "xcecd_worker_utils.h"
#include "xcecd_utils.h"
#include "xcelog.h"
/**
* @brief start worker without resource limits (disabled by default)
* @param command command with arguments
* @return 0 if success, -1 if failed
*/
int process_manager_start_worker(process_manager_t* manager);
/**
* @brief update the process status in the list
* @param manager process manager
* @param worker worker process
* @param job XCE job information
* @param db database information
* @return 0 if success, -1 if failed
*/
bool worker_process_update(process_manager_t* manager,
xcecd_worker_t* worker,
xcecd_job_t* job,
sqlite3* db);
#endif // _PROCESS_WORKER_MANAGER_H_

View file

@ -0,0 +1,29 @@
#ifndef RESOURCE_SYNC_H
#define RESOURCE_SYNC_H
#include "hardware_monitor.h"
#include "node_information.h"
#include <stdbool.h>
// 资源同步模块结构体
typedef struct resource_sync resource_sync_t;
// 创建资源同步模块
resource_sync_t* resource_sync_create(void);
// 销毁资源同步模块
void resource_sync_destroy(resource_sync_t* sync);
// 启动资源同步模块
bool resource_sync_start(resource_sync_t* sync);
// 停止资源同步模块
void resource_sync_stop(resource_sync_t* sync);
// 更新资源同步模块
bool resource_sync_update(resource_sync_t* sync);
// 读取资源同步模块
void resource_sync_read(resource_sync_t* sync, host_node_t** node);
#endif // RESOURCE_SYNC_H

View file

@ -0,0 +1,33 @@
#ifndef _STATIC_ARRAY_H_
#define _STATIC_ARRAY_H_
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <pthread.h>
#define MAX_ARRAY_SIZE 128
typedef struct {
unsigned char data[MAX_ARRAY_SIZE * 64];
size_t element_size;
size_t count;
pthread_mutex_t lock;
} StaticArray;
void init_static_array(StaticArray* arr, size_t element_size);
bool push_static(StaticArray* arr, void* value);
bool pop_static(StaticArray* arr, void* out_value);
bool pop_static_from_bottom(StaticArray* arr, void* out_value);
void clear_static(StaticArray* arr);
bool get_element(StaticArray* arr, size_t index, void* out_value);
#endif // _STATIC_ARRAY_H_

View file

@ -0,0 +1,29 @@
#ifndef SYSTEM_MONITOR_H
#define SYSTEM_MONITOR_H
#include <stdint.h>
#include <stdbool.h>
typedef struct {
double cpu_usage; // CPU使用率(百分比)
uint64_t memory_total; // 总内存(字节)
uint64_t memory_used; // 已使用内存(字节)
uint64_t disk_total; // 总磁盘空间(字节)
uint64_t disk_used; // 已使用磁盘空间(字节)
} system_status_t;
typedef struct system_monitor system_monitor_t;
// 创建系统监控器
system_monitor_t* system_monitor_create(void);
// 获取当前系统状态
const system_status_t* system_monitor_get_status(system_monitor_t* monitor);
// 更新系统状态
bool system_monitor_update(system_monitor_t* monitor);
// 销毁系统监控器
void system_monitor_destroy(system_monitor_t* monitor);
#endif // SYSTEM_MONITOR_H

View file

@ -0,0 +1,100 @@
#ifndef THREAD_POOL_H
#define THREAD_POOL_H
#include "xcecd_utils.h"
#include "xcecd_cgroups.h"
#include <stddef.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
#define IPC_BUFFER_SIZE 256
#define MAX_MSG_SIZE 4096
#define MAX_QUEUE_SIZE 1024
// 任务函数类型
typedef void (*task_func_t)(void* arg);
// 作业执行任务消息队列
typedef struct {
pid_t target_pid;
uint32_t ntasks;
uint32_t clientidx;
uint64_t xce_jobid;
task_func_t func;
job_startinfo_t* startinfo;
res_limits_t* limits;
#ifndef DBUS_MANAGER
void* manager;
#endif
} fork_task_t;
//作业控制消息队列
typedef struct {
uint64_t jobid;
pid_t target_pid;
int signal;
int force;
bool checkpoint;
int ckpt_kill;
char* ckpt_method;
task_func_t func;
} job_control_task_t;
// 消息队列结构
typedef struct {
void *messages;
task_func_t* func;
size_t msg_size;
size_t capacity;
size_t head;
size_t tail;
size_t count;
pthread_mutex_t lock;
pthread_cond_t not_empty;
pthread_cond_t not_full;
} message_queue_t;
typedef struct {
long system_tid; // 系统线程ID
size_t pool_tid; // 线程池中的线程ID (1-N)
} thread_id_map_t;
typedef struct {
size_t num_threads;
pthread_t* threads;
bool running;
thread_id_map_t* thread_map;
message_queue_t fork_queue;
message_queue_t control_queue;
} thread_pool_t;
enum {
JOB_CONTROL_STOP,
JOB_CONTROL_PAUSE,
JOB_CONTROL_RESUME,
JOB_CONTROL_RESTART,
JOB_CONTROL_KILL,
JOB_CONTROL_STATUS
};
thread_pool_t* thread_pool_create(size_t num_threads);
void thread_pool_destroy(thread_pool_t* pool);
message_queue_t* message_queue_create(size_t capacity, size_t msg_size);
void message_queue_destroy(message_queue_t* queue);
int queue_push(message_queue_t* queue, void* message);
int queue_pop(message_queue_t* queue, void* message);
int submit_fork_task(thread_pool_t* pool, fork_task_t* task);
int submit_job_control_task(thread_pool_t* pool, job_control_task_t* task);
void job_control_signal(void* arg);
#endif // THREAD_POOL_H

170
src/worker/include/uv_ipc.h Normal file
View file

@ -0,0 +1,170 @@
#ifndef UV_IPC_H
#define UV_IPC_H
#include "xcecd_utils.h"
#include "uv.h"
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
#define HOSTNAME_LENGTH 256
#define MESSAGE_LENGTH 256
#define COMMAND_LENGTH 4096
#define METHOD_LENGTH 64
#define PATH_LENGTH 1024
#define EXDATA_LENGTH 16 * 1024
typedef enum {
MSG_GET_JOB,
MSG_JOB_ASSIGNED,
MSG_JOB_STATUS,
MSG_JOB_COMPLETED,
MSG_JOB_SIGNAL,
MSG_JOB_SIGNAL_ACK,
MSG_JOB_CKPT,
MSG_JOB_CKPT_ACK,
MSG_JOB_CKPT_RESULT,
MSG_REMOTE_START_JOB,
MSG_REMOTE_START_JOB_ACK,
MSG_HEARTBEAT,
MSG_ERROR
} message_type_t;
typedef struct {
int type;
} heartbeat_message_t;
typedef struct {
uint64_t job_id;
int job_pid;
int status_code;
int worker_pid;
int worker_status;
int exit_code;
int stage;
bool post_done;
char status_message[MESSAGE_LENGTH];
char start_exdata[MAXLINELEN];
} job_status_t;
typedef struct {
uint64_t job_id;
int ntasks;
char cmd[COMMAND_LENGTH];
char q_pre_exec[COMMAND_LENGTH];
char q_post_exec[COMMAND_LENGTH];
char job_pre_exec[COMMAND_LENGTH];
char job_post_exec[COMMAND_LENGTH];
char exdata[EXDATA_LENGTH];
} job_assignment_t;
typedef struct {
uint64_t job_id;
int signal;
bool force;
} job_signal_t;
typedef struct {
uint64_t job_id;
int kill; // 0: do not kill process
char method[METHOD_LENGTH];
char img_path[PATH_LENGTH];
char parent_path[PATH_LENGTH];
} job_ckpt_t;
typedef struct {
uint64_t job_id;
int status; // 0: success, 1: fail
char restore_cmd[COMMAND_LENGTH];
} job_ckpt_result_t;
typedef struct {
uint64_t jobid;
char hostname[HOSTNAME_LENGTH];
char command[COMMAND_LENGTH];
} remote_start_job_t;
typedef struct {
int success; // 1: success, 0: failure
char error_message[MESSAGE_LENGTH];
} remote_start_job_ack_t;
typedef struct {
message_type_t type;
union {
job_status_t status;
job_assignment_t assignment;
job_signal_t signal;
job_ckpt_t ckpt;
job_ckpt_result_t ckpt_result;
remote_start_job_t remote_start;
remote_start_job_ack_t remote_start_ack;
char error_message[MESSAGE_LENGTH];
} data;
int worker_pid;
} ipc_message_t;
//#undef FREEUP
//#define FREEUP(ptr) do { if (ptr) { free(ptr); ptr = NULL; } } while(0)
extern int child_processes;
extern int active_jobs;
extern int exit_flag;
extern uv_loop_t* loop;
typedef void (*job_callback_t)(job_assignment_t* info);
typedef void (*connection_callback_t)(bool success);
typedef void (*worker_reconnect_callback_t)(bool connected);
typedef void (*job_status_callback_t)(job_status_t* job_status);
typedef void (*client_disconnect_callback_t)(uint64_t client_id);
typedef void (*heartbeat_callback_t)(uv_stream_t* client);
typedef void (*job_signal_callback_t)(uint64_t job_id, int signal, bool force);
typedef void (*job_ckpt_callback_t)(uint64_t job_id, int kill, const char* method);
typedef void (*job_ckpt_result_callback_t)(uint64_t job_id, int status, const char* restore_cmd);
bool ipc_master_init(const char* socket_path);
void ipc_master_run(uv_run_mode mode);
void ipc_master_stop();
bool ipc_master_check_connection();
void ipc_master_set_status_callback(job_status_callback_t callback);
void ipc_master_set_disconnect_callback(client_disconnect_callback_t callback);
void ipc_master_set_heartbeat_callback(heartbeat_callback_t callback);
bool ipc_master_send_job_signal(uint64_t job_id, int signal, bool force);
bool ipc_master_send_job_ckpt(uint64_t job_id, int kill, const char* method);
void ipc_master_set_ckpt_callback(job_ckpt_callback_t callback);
void ipc_master_set_ckpt_result_callback(job_ckpt_result_callback_t callback);
bool ipc_worker_init(const char* socket_path);
void ipc_worker_connect(connection_callback_t callback);
void ipc_worker_reconnect(worker_reconnect_callback_t callback);
void ipc_worker_run(uv_run_mode mode);
void ipc_worker_stop();
void ipc_worker_set_job_callback(job_callback_t callback);
void ipc_worker_set_reconnection_callback(worker_reconnect_callback_t callback);
void ipc_worker_request_job();
void ipc_worker_send_status(job_runtime_info_t* job_info,
const char* status_message);
void ipc_worker_job_completed(uint64_t job_id);
bool ipc_worker_check_connection();
void ipc_worker_send_signal_ack(uint64_t job_id, int signal, bool force);
void ipc_worker_set_signal_callback(job_signal_callback_t callback);
bool ipc_worker_send_ckpt_ack(uint64_t job_id, int kill, const char* method);
void ipc_worker_set_ckpt_callback(job_ckpt_callback_t callback);
bool ipc_worker_send_ckpt_result(uint64_t job_id, int status, const char* restore_cmd);
void on_write_complete(uv_write_t* req,
int status);
uv_loop_t* ipc_get_event_loop();
#ifdef __cplusplus
}
#endif
#endif /* UV_IPC_H */

182
src/worker/include/uv_proc.h Executable file
View file

@ -0,0 +1,182 @@
#ifndef UV_PROC_H
#define UV_PROC_H
#include "uv.h"
#include <stdbool.h>
#include <stdint.h>
/**
* process status enumeration
*/
typedef enum {
UV_PROC_IDLE,
UV_PROC_RUNNING,
UV_PROC_COMPLETED,
UV_PROC_ERROR,
UV_PROC_TERMINATED,
UV_PROC_UNKNOWN
} uv_proc_status_t;
/**
* process exit callback function type
* @param pid process ID
* @param exit_status exit status code
* @param term_signal termination signal (if terminated by signal)
* @param user_data user data passed to the callback
*/
typedef void (*uv_proc_exit_cb)(int pid, int exit_status,
int term_signal, void* user_data);
/**
* process manager structure
*/
typedef struct uv_proc_manager_s {
uint64_t job_id; // job ID
uv_loop_t* loop; // event loop shared with ipc
uv_process_t* active_proc; // current active process
uv_proc_status_t status; // current process status
int last_exit_code; // last exit code
int last_term_signal; // last termination signal
void* user_data; // user data for callback
uv_proc_exit_cb exit_cb; // exit callback function
uv_process_t** proc_list;
int proc_count;
int proc_capacity;
int remaining_procs;
} uv_proc_manager_t;
/**
* initialize the process manager
*
* @param manager process manager pointer
* @param loop event loop pointer
* @return 0 on success, non-zero error code on failure
*/
int uv_proc_init(uv_proc_manager_t* manager,
uv_loop_t* loop);
/**
* pre-execute a command (blocking execution, not managed by event loop)
*
* @param manager process manager pointer
* @param command pre-execute command
* @param args command arguments
* @return 0 on success, non-zero error code on failure
*/
int uv_proc_pre_exec(uv_proc_manager_t* manager,
const char* command, char* const args[]);
/**
* asynchronously execute a command (managed by event loop)
*
* @param manager process manager pointer
* @param command command to execute
* @param args command arguments
* @param exit_cb exit callback function
* @param user_data user data passed to the callback
* @return 0 on success, non-zero error code on failure
*/
int uv_proc_exec(uv_proc_manager_t* manager, const char* command, char* const args[],
uv_proc_exit_cb exit_cb, void* user_data, int ntasks);
/**
* post-execute a command (blocking execution, not managed by event loop)
*
* @param manager process manager pointer
* @param command post-execute command
* @param args command arguments
* @return 0 on success, non-zero error code on failure
*/
int uv_proc_post_exec(uv_proc_manager_t* manager,
const char* command, char* const args[]);
/**
* send a signal to the current process
*
* @param manager process manager pointer
* @param signum signal number
* @return 0 on success, non-zero error code on failure
* @note this function does not wait for the process to exit
*/
int uv_proc_kill(uv_proc_manager_t* manager, int signum);
/**
* get the current process status
*
* @param manager process manager pointer
* @return current process status
*/
uv_proc_status_t uv_proc_get_status(uv_proc_manager_t* manager);
/**
* get the current process ID
*
* @param manager process manager pointer
* @return process ID
*/
int uv_proc_get_pid(uv_proc_manager_t* manager);
/**
* get the last exit code
*
* @param manager process manager pointer
* @return exit code
*/
int uv_proc_get_exit_code(uv_proc_manager_t* manager);
/**
* get the last termination signal
*
* @param manager process manager pointer
* @return termination signal
*/
int uv_proc_get_term_signal(uv_proc_manager_t* manager);
/**
* cleanup the process manager
*
* @param manager process manager pointer
*/
void uv_proc_cleanup(uv_proc_manager_t* manager);
/**
* wait for the process to exit
*
* @param manager process manager pointer
* @param timeout_ms timeout in milliseconds (0 for infinite wait)
* @return 0 on success, non-zero error code on failure
*/
int uv_proc_wait(uv_proc_manager_t* manager, int timeout_ms);
/**
* pre-execute a command in background mode
*
* @param manager process manager pointer
* @param command command to execute
* @param args command arguments
* @param background whether to run in background mode (1 for yes, 0 for no)
* @return 0 on success, non-zero error code on failure
*/
int uv_proc_pre_exec_background(uv_proc_manager_t* manager,
const char* command,
char* const args[],
int background);
/**
* execute a command in single-task mode
*
* @param manager process manager pointer
* @param command command to execute
* @param args command arguments
* @param exit_cb exit callback function
* @param user_data user data passed to the callback
* @return 0 on success, non-zero error code on failure
*/
int uv_proc_exec_single(uv_proc_manager_t* manager,
const char* command,
char* const args[],
uv_proc_exit_cb exit_cb,
void* user_data);
#endif /* UV_PROC_H */

104
src/worker/include/xcecd.h Normal file
View file

@ -0,0 +1,104 @@
#ifndef XCECD_H
#define XCECD_H
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include "xcecd_conf.h"
#include "thread_pool.h"
#include "controller_connector.h"
#include "process_manager.h"
#include "system_monitor.h"
#include "hardware_monitor.h"
#include "resource_sync.h"
#include "node_information.h"
#include "job_information.h"
#include "xcecd_worker_utils.h"
#include "xcecd_dbus_manager.h"
#include "static_array.h"
#include "uv_ipc.h"
#include "xcecd_db.h"
#include "xcelog.h"
#include "xcectx.h"
#ifdef _WIN32
#include <windows.h>
#include <winsock2.h>
#include <pdh.h>
typedef HANDLE process_handle_t;
#else
#include <unistd.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef pid_t process_handle_t;
#endif
#define REMOTE_PORT 6789
#define DEFAULT_PORT 0 // disable by default
#define BUFFER_SIZE 4096
#define RESTART_FLAG_FILE "/tmp/.xcecd.restarting"
typedef struct {
int thread_pool_size;
int resource_update_interval;
int job_status_update_interval;
uint16_t port;
const char* acct_file;
char* log_file;
const char* db_path;
const char* work_dir;
const char* domain_sock_file;
const char* remote_host;
const char* virutal_name;
int remote_port;
int join_interval;
int update_interval;
int domain_sock;
int debug_level;
} xcecd_config_t;
typedef struct {
thread_pool_t* thread_pool;
network_handler_t* network;
process_manager_t* process_manager;
system_monitor_t* system_monitor;
hardware_monitor_t* hardware_monitor;
resource_sync_t* resource_sync;
xcecd_worker_t* worker_list;
xcecd_db_t *db;
xce_ctx_t* xce_ctx;
bool running;
bool normal_restart;
char* remote_host;
int local_port;
int remote_port;
int update_interval;
int join_interval;
int domain_sock;
int debug_level;
char* work_dir;
char* log_dir;
char* db_path;
char* virtual_name;
} xcecd_context_t;
extern xcecd_context_t xcecd_ctx;
extern hostattrs_t host_attrs;
int xcecd_config_init(xcecd_config_t* config);
int xcecd_init(const xcecd_config_t* config);
int xcecd_start(void);
void xcecd_stop(void);
void xcecd_cleanup(void);
int send_status_and_receive_tasks(void);
void xcecd_process_command(void* arg);
const char* handle_network_request(const char* request, void* user_data);
bool xcecd_config_is_valid(const xcecd_config_t* config);
void xcecd_prepare_restart(void);
bool xcecd_check_restart_type(void);
#endif // XCECD_H

View file

@ -0,0 +1,99 @@
#ifndef _XCECD_CGROUPS_H_
#define _XCECD_CGROUPS_H_
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <systemd/sd-bus.h>
typedef struct {
// CPU limit
uint64_t cpu_quota; // CPU quota in microseconds (e.g. 200000 = 20%, cpu_limit)
uint64_t cpu_period; // CPU period in microseconds (e.g. 1000000 = 1 second)
uint32_t cpu_weight; // CPU weight (e.g. 100 = default)
uint64_t cpu_limit; // CPU limit (run time limit in seconds)
uint64_t core_limit; // Core limit (in number of cores, e.g. 2 = 2 cores)
char *cpu_affinity; // CPU affinity list (e.g. "0,1,2")
// Memory limit
uint64_t memory_max; // Maximum memory usage (rss_limit)
uint64_t memory_high; // Memory high usage level (in bytes)
uint64_t memory_swap_max; // Maximum swap space usage (swap_limit)
// IO limit
uint64_t io_weight; // IO weight (e.g. 100 = default)
uint64_t io_read_bps_max; // Maximum read speed (bytes/second)
uint64_t io_write_bps_max; // Maximum write speed (bytes/second)
char *io_device_path; // IO device path (e.g. "/dev/sda")
// Tasks limit
uint64_t tasks_max; // Max number of threads (thread_limit)
uint64_t run_limit; // Max run time (in seconds)
uint64_t core_size_limit; // Max core file size (in bytes)
uint64_t data_limit; // Max data size (in bytes)
uint64_t fsize_limit; // Max file size (in bytes)
uint64_t stack_limit; // Max stack size (in bytes)
uint64_t process_limit; // Max number of processes
// OOM score
int32_t oom_score_adjust; // OOM (-1000 to 1000)
char *user_name; // User name
} res_limits_t;
/**
* start worker with resource limits
* @param command command with arguments
* @param limits resource limits (NULL if no limits)
* @param unit_name_prefix unit name prefix, NULL for default prefix
* @param job_id job id
* @param extra_args extra command line arguments (NULL if none)
* @return unit name if success, NULL if failed
*/
char* start_systemd_job(const char* command,
const res_limits_t* limits,
const char* unit_name_prefix,
uint64_t job_id,
char* extra_args);
/**
* Get PID of a systemd job
* @param unit_name unit name
* @return PID if success, -1 if failed
*/
pid_t get_systemd_job_pid(const char* unit_name);
/**
* Stop a systemd job
* @param unit_name unit name
* @return 0 if success, -1 if failed
*/
int stop_systemd_job(const char* unit_name);
/**
* Check if a systemd job is active
* @param unit_name unit name
* @return true if active, false if not active
*/
bool is_systemd_job_active(const char* unit_name);
/**
* Get systemd job exit code
* @param unit_name unit name
* @return exit code if success, -1 if failed
*/
int get_systemd_job_exit_code(const char* unit_name);
/**
* @brief Get systemd job status text
* @param unit_name unit name
* @return status text if success, NULL if failed.
* Caller must free the returned string.
*/
char* get_systemd_job_status_text(const char* unit_name);
#endif // _XCECD_CGROUPS_H_

View file

@ -0,0 +1,47 @@
#ifndef XCECD_CONF_H
#define XCECD_CONF_H
#include <cyaml/cyaml.h>
#include <stdint.h>
#include <stdbool.h>
#define DEFAULT_CONFIG_PATH "/opt/xce/conf/worker.yaml"
#define MAX_HOSTNAME_LEN 256
#define MAX_PATH_LEN 512
#define MAX_LOG_LEVEL_LEN 16
typedef enum {
CONFIG_SUCCESS = 0,
CONFIG_ERROR_FILE_NOT_FOUND,
CONFIG_ERROR_PARSE_FAILED,
CONFIG_ERROR_INVALID_DATA,
CONFIG_ERROR_MEMORY,
CONFIG_ERROR_UNKNOWN
} config_error_t;
typedef struct {
char *hostname;
} management_host_t;
typedef struct {
management_host_t *management_list;
uint32_t management_list_count;
uint16_t controller_port;
char *log_level;
char *log_dir;
} worker_config_t;
typedef struct {
config_error_t error_code;
char error_message[512];
worker_config_t *config;
} config_result_t;
config_result_t* config_load(const char *config_path);
config_result_t* config_load_default(void);
void config_free(config_result_t *result);
const char* config_error_string(config_error_t error);
void config_print(const worker_config_t *config);
int level_to_int(const char *level);
#endif // XCECD_CONF_H

View file

@ -0,0 +1,97 @@
#ifndef _XCECD_DB_H
#define _XCECD_DB_H
#include "sqlite3.h"
#include "xcecd_worker_utils.h"
#include "xcecd_utils.h"
#include <stdint.h>
#include <stdbool.h>
typedef struct sqlite3 xcecd_db_t;
/**
* @brief Initialize the database
*
* @param db Pointer to the database structure
* @param db_path Path to the database file
* @return true if success, false if failed
*/
bool xcecd_db_init(xcecd_db_t** db,
const char* db_path);
/**
* @brief close the database
* @param db Pointer to the database structure
*/
void xcecd_db_close(xcecd_db_t* db);
/**
* @brief Insert a worker into the database
*
* @param db Pointer to the database structure
* @param worker_pid PID of the worker
* @param worker_status Status of the worker
* @param job_id Job ID associated with the worker
* @param job_status Status of the job associated with the worker
* @return true if success, false if failed
*/
bool xcecd_db_insert_worker(xcecd_db_t* db,
int worker_pid,
int worker_status,
uint64_t job_id,
int job_status);
/**
* @brief Update a worker in the database
*
* @param db Pointer to the database structure
* @param worker_pid PID of the worker
* @param worker_status Status of the worker
* @param job_status Status of the job associated with the worker
* @return true if success, false if failed
*/
bool xcecd_db_update_worker(sqlite3* db,
int worker_pid,
int worker_status,
int job_status);
/**
* @brief Delete a worker from the database
*
* @param db Pointer to the database structure
* @param worker_pid PID of the worker
* @return true if success, false if failed
*/
bool xcecd_db_delete_worker(xcecd_db_t* db,
int worker_pid);
/**
* @brief Get a worker from the database
*
* @param db Pointer to the database structure
* @param worker_pid PID of the worker
* @return worker status if success, -1 if failed
*/
int xcecd_db_get_worker(xcecd_db_t* db,
int worker_pid);
/**
* @brief Get running workers from the database
*
* @param db Pointer to the database structure
* @return Pointer to the worker list (db->worker_list) if success, NULL if failed
*/
bool xcecd_db_get_running_workers(xcecd_db_t* db,
xcecd_worker_t** worker_list);
/**
* @brief Check if the database is available
* @param db Pointer to the database structure
* @param db_path Path to the database file
* @return void and directly exit if the database is not available
*/
void xcecd_db_is_available(xcecd_db_t* db,
const char* db_path);
#endif

View file

@ -0,0 +1,82 @@
/**
* @file xcecd_dbus_manager.h
* @brief This file contains the declaration of the D-Bus manager functions.
* It uses to manage worker and its child process with resource limits.
*/
#ifndef _XCECD_DBUS_MANAGER_H_
#define _XCECD_DBUS_MANAGER_H_
#include "sqlite3.h"
#include "xcecd_cgroups.h"
#include "xcecd_worker_utils.h"
#include "xcecd_utils.h"
#include <stdbool.h>
/**
* @brief Start worker with resource limits
*
* @param limits resource limits (NULL if no limits)
* @param job_id job id
* @param extra_args extra command line arguments (NULL if none)
* @return true if success, false if failed
*/
bool dbus_start_worker(const res_limits_t* limits,
uint64_t job_id, char* extra_args);
/**
* @brief Stop a worker service
*
* @param unit_name worker service name (xcecd-worker-<job_id>.service)
* @return true if success, false if failed
*/
bool dbus_stop_worker(const char* unit_name);
/**
* @brief Get PID of a worker service
*
* @param unit_name worker service name (xcecd-worker-<job_id>.service)
* @return PID if success, -1 if failed
*/
pid_t dbus_get_worker_pid(const char* unit_name);
/**
* @brief Check if a worker service is active
*
* @param unit_name worker service name (xcecd-worker-<job_id>.service)
* @return true if active, false if not active
*/
bool dbus_is_worker_active(const char* unit_name);
/**
* @brief Update worker status
*
* @param worker_list worker list
* @param job job information
* @param db database information
* @return XCECD_OK if success, others in execd_error if failed
*/
int dbus_workers_update(xcecd_worker_t** worker_list,
xcecd_job_t* job,
sqlite3* db);
/**
* @brief Clean worker service
*
* @param worker worker information
* @param job job information
* @return true if success, false if failed
*/
bool dbus_worker_clean(xcecd_worker_t* worker,
xcecd_job_t* job);
/**
* @brief Go through worker list and stop all workers
* @param worker_list worker list
* @param db database information
* @return void
*/
void dbus_stop_all_workers(xcecd_worker_t** worker_list,
sqlite3* db);
#endif // _XCECD_DBUS_MANAGER_H_

View file

@ -0,0 +1,52 @@
#ifndef _XCECD_EXDATA_H
#define _XCECD_EXDATA_H
#include <cjson/cJSON.h>
#include "xcecd_cgroups.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
typedef struct env_var {
char* key;
char* value;
struct env_var* next;
} env_var_t;
typedef struct {
char* local_file;
char* remote_file;
char* op;
} transfer_file_t;
typedef struct {
transfer_file_t* ops;
int interactive_mode;
int count;
} transfer_info_t;
typedef struct {
char* url;
} start_exdata_t;
bool parse_exdata(const char* exdata,
env_var_t** env_vars,
transfer_info_t* transfer_infos,
uint64_t jobid);
bool parse_limits(const char* exdata,
res_limits_t *limits);
void apply_env_vars(env_var_t** env_vars,
uint64_t jobid);
void free_transfer_info(transfer_info_t* transfer_info);
char* generate_exdata(const start_exdata_t* start_info);
#endif /* _XCECD_EXDATA_H */

View file

@ -0,0 +1,127 @@
#ifndef XCECD_UTILS_H
#define XCECD_UTILS_H
#include <stdbool.h>
#include "xce/types.h"
#include "utils.h"
/* This header file has some utilities and structure for compatibility with
* other scheduler systems. */
#define XCE_DEFAULT_SOCKS 15
#define MAXPATHLEN 1024
#define MAXHOSTNAMELEN 256
#define MAXLINELEN 4096
#define MAXDATASIZE (16 * 1024)
#define MAXXCENAMELEN 40
#define MAXSRES 32
#define MAXRESDESLEN 256
#define NBUILTINDEX 11
#define MAXTYPES 128
#define MAXMODELS 128
#define MAXTYPES_31 25
#define MAXMODELS_31 30
#define MAXFILENAMELEN 256
#define MAX_CONCURRENT_JOBS 200
struct windows {
struct windows * nextwind;
float opentime;
float closetime;
};
typedef struct windows windows_t;
enum value_type {LS_BOOLEAN, LS_NUMERIC, LS_STRING, LS_EXTERNAL};
#define BOOLEAN LS_BOOLEAN
#define NUMERIC LS_NUMERIC
#define STRING LS_STRING
#define EXTERNAL LS_EXTERNAL
enum order_type {INCR, DECR, NA};
struct res_item {
char name[MAXXCENAMELEN];
char des[MAXRESDESLEN];
enum value_type value_type;
enum order_type order_type;
int flags;
int interval;
};
struct is_info {
int num_res;
struct res_item *res_table;
int num_types;
char host_types[MAXTYPES][MAXXCENAMELEN];
int num_models;
char host_models[MAXMODELS][MAXXCENAMELEN];
char host_archs[MAXMODELS][MAXXCENAMELEN];
int model_refs[MAXMODELS];
float cpu_factor[MAXMODELS];
int num_indx;
int num_usr_indx;
};
#define GET_INTNUM(i) ((i)/INTEGER_BITS + 1)
enum job_status {
JOB_PENDING,
JOB_STARTING,
JOB_RUNNING,
JOB_SUSPENDED,
JOB_DONE,
JOB_REMOVED,
JOB_EXITED,
JOB_FAILED,
JOB_UNKNOWN
};
enum {
WORKER_RUNNING = 0,
WORKER_DONE,
WORKER_EXITED,
WORKER_UNKNOWN
};
enum execd_error {
XCECD_OK = 0,
XCECD_ERROR,
XCECD_TIMEOUT,
XCECD_NO_MEMORY,
XCECD_INVALID_PARAM,
XCECD_NOT_FOUND,
XCECD_DB_ERROR,
XCECD_NOT_SUPPORTED
};
typedef struct {
uint64_t job_id;
int job_pid;
int job_status;
int exit_code;
int stage;
int interactive_port;
char exdata[MAXDATASIZE];
} xcecd_job_t;
typedef struct {
uint64_t job_id;
pid_t job_pid;
pid_t worker_pid;
int job_status;
int worker_status;
int exit_code;
int stage;
bool post_done;
int interactive_port;
char q_pre_exec[MAXLINELEN];
char q_post_exec[MAXLINELEN];
char job_pre_exec[MAXLINELEN];
char job_post_exec[MAXLINELEN];
char exdata[MAXDATASIZE];
} job_runtime_info_t;
void block_signal(int sig);
void unblock_signal(int sig);
#endif

View file

@ -0,0 +1,101 @@
#ifndef XCED_WORKER_UTILS_H
#define XCED_WORKER_UTILS_H
#include "sqlite3.h"
#include "job_information.h"
#include "xcecd_utils.h"
#include "xcelog.h"
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
struct xcecd_worker {
int worker_pid;
int worker_status;
int job_status;
int job_exit_code;
int ntasks;
char *exechome;
char *execcwd;
char *execuser;
char *job_cmd;
char *job_exdata;
char *launch_type;
char *q_pre_exec;
char *q_post_exec;
char *job_pre_exec;
char *job_post_exec;
struct xcecd_worker *prev;
struct xcecd_worker *next;
xce_job_runinfo_t job_info;
#ifdef VIRTUAL_CLUSTER
time_t start_time;
int sleep_time;
int killed_signal;
#endif
};
struct xcecd_db_t;
typedef struct xcecd_worker xcecd_worker_t;
/* TODO: New Worker states */
typedef enum {
SERVICE_UNKNOWN = 0,
SERVICE_ACTIVE,
SERVICE_INACTIVE,
SERVICE_ACTIVATING,
SERVICE_DEACTIVATING,
SERVICE_FAILED,
SERVICE_RELOADING
} service_state_t;
void add_worker(xcecd_worker_t** worker_list,
int worker_pid,
int worker_status,
uint64_t job_id,
int ntasks,
job_startinfo_t* startinfo);
void remove_worker(xcecd_worker_t** worker_list,
int worker_pid);
int update_worker_status(xcecd_worker_t* worker_list,
int worker_pid,
int worker_status,
xcecd_job_t* job,
sqlite3* db);
/* Cleanup the worker in the list which finished work */
void cleanup_worker_list(xcecd_worker_t** worker_list,
sqlite3* db);
xcecd_worker_t* find_worker_by_pid(void* worker_list,
int pid);
xcecd_worker_t* find_worker_by_jobid(xcecd_worker_t* worker_list,
uint64_t jobid);
extern bool xcecd_reply_startjob(xcecd_job_t *job);
extern int xcecd_job_stopped(uint64_t job_id);
extern int xcecd_job_resumed(uint64_t job_id);
extern int xcecd_job_finished(xcecd_job_t *job);
extern bool xcecd_db_update_worker(sqlite3* db,
int worker_pid,
int worker_status,
int job_status);
extern bool xcecd_db_delete_worker(sqlite3* db,
int worker_pid);
bool resend_job_status(xcecd_worker_t* worker_list);
#ifdef VIRTUAL_CLUSTER
bool check_worker_sleep_time_elapsed(xcecd_worker_t* worker);
#endif
#endif // XCED_WORKER_UTILS_H

20
src/worker/include/xrun.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef XRUN_H
#define XRUN_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <stdbool.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
int xrun_ipc_send_remote_start(const char *hostname, const char *command);
int run_remote_command(const char *hostname, const char *command);
void setup_signal_handlers(void);
void handle_signal(int sig);
#endif // XRUN_H