| /*
* Sai builder definitions src/builder/b-private.h
*
* Copyright (C) 2019 - 2025 Andy Green <andy@warmcat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation:
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include "../common/include/private.h"
#if !defined(WIN32)
#include <pwd.h>
#include <grp.h>
#endif
#if defined(__linux__) || defined(__APPLE__)
#include <unistd.h>
#endif
#if defined(__APPLE__)
#include <sys/stat.h> /* for mkdir() */
#include <sys/wait.h>
#endif
#if defined(WIN32)
#include <initguid.h>
#include <KnownFolders.h>
#include <Shlobj.h>
#include <processthreadsapi.h>
#include <handleapi.h>
#if !defined(PATH_MAX)
#define PATH_MAX MAX_PATH
#endif
#endif
#include <sys/stat.h>
#if defined(WIN32)
#include <direct.h>
#define read _read
#define open _open
#define close _close
#define write _write
#define mkdir(x,y) _mkdir(x)
#define rmdir _rmdir
#define unlink _unlink
#if defined(pid_t)
#undef pid_t
#endif
#endif
#include <pthread.h>
extern char suspender_exists;
struct lws_spawn_piped;
struct lws_stub_manager;
struct saib_opaque_spawn {
struct sai_nspawn *ns;
struct lws_spawn_piped *lsp;
char *spawn;
lws_usec_t start_time;
};
#define SAI_LOAD_REPORT_US (1 * LWS_US_PER_SEC)
#define SAI_IDLE_GRACE_US (builder.one_shot_active ? (10 * LWS_US_PER_SEC) : (30 * LWS_US_PER_SEC))
#define SAI_STAY_POLL_US (20 * LWS_US_PER_SEC)
#define SAI_CLEANUP_JOBS_INTERVAL_US (60ULL * 60ULL * LWS_US_PER_SEC)
#define SAI_CLEANUP_JOB_DIR_MIN_AGE_SECS (24ull * 3600u)
struct saib_ws_pss;
enum nsstate {
NSSTATE_INIT,
NSSTATE_MOUNTING,
NSSTATE_EXECUTING_STEPS,
NSSTATE_DONE,
NSSTATE_UPLOADING_ARTIFACTS,
NSSTATE_FAILED,
};
/*
* This represents this builder process as a whole
*/
struct sai_shell {
struct lws_dll2 list;
char task_uuid[33];
struct sai_plat_server *spm;
struct lws_spawn_piped *lsp;
struct lws *stdwsi[3];
char stdwsi_paused[3];
int user_cancel;
};
struct sai_builder {
lws_dll2_owner_t sai_plat_owner; /* list of platforms we offer */
lws_dll2_owner_t sai_plat_server_owner; /* servers we connect to */
lws_dll2_owner_t devices_owner; /* sai_serial_t */
lws_dll2_owner_t lsp_owner; /* list of lws_spawn_piped */
lws_dll2_owner_t shell_owner; /* list of sai_shell */
struct lws_ss_handle *ss_stay;
struct lws_ss_handle *ss_power_off;
struct sai_nspawn suspend_nspawn;
struct lwsac *conf_head;
struct lws_context *context;
struct lws_vhost *vhost;
lws_sorted_usec_list_t sul_idle;
lws_sorted_usec_list_t sul_do_suspend;
lws_sorted_usec_list_t sul_do_shutdown;
lws_sorted_usec_list_t sul_stay;
lws_sorted_usec_list_t sul_cleanup_jobs;
#if defined(__APPLE__)
lws_sorted_usec_list_t sul_release_wakelock;
pid_t wakelock_pid;
#endif
const char *metrics_uri;
const char *metrics_path;
const char *metrics_secret;
const char *url_sai_power;
const char *power_controller_name;
const char *power_off_type;
const char *power_off_url;
const char *power_on_type;
const char *power_on_url;
const char *power_on_mac;
const char *power_monitor_url;
const char *home; /* home dir, usually /sai/home */
const char *perms; /* user:group */
const char *host; /* prepended before hostname */
const char *rebuild_script_user;
const char *rebuild_script_root;
char path[256];
char path_power_off[256];
#if defined(__linux__) || defined(__APPLE__)
/* For system-wide load calculation */
uint64_t last_sys_total;
uint64_t last_sys_idle;
#elif defined(WIN32)
ULARGE_INTEGER last_sys_total;
ULARGE_INTEGER last_sys_idle;
ULARGE_INTEGER last_sys_kernel;
ULARGE_INTEGER last_sys_user;
#endif
char stay;
char event_affinity[65];
char event_affinity_active;
char one_shot_task_uuid[65];
char one_shot_active;
/* resource management */
uint64_t ram_limit_kib;
uint64_t ram_reserved_kib;
uint64_t disk_total_kib;
uint64_t disk_reserved_kib;
uint16_t wrap14;
unsigned int build_timeout_secs;
#if !defined(WIN32)
int pipe_suspender_wr;
#else
void *pipe_suspender_wr;
#endif
struct lws_stub_manager *mgr_deletion;
};
struct jpargs {
struct sai_builder *builder;
struct sai_nspawn *nspawn;
struct sai_plat *sai_plat;
struct sai_platform *pl;
sai_plat_server_ref_t *mref;
int next_server_index;
int next_plat_index;
};
struct ws_capture_chunk {
struct lws_dll2 list;
lws_usec_t us; /* builder time that we saw this */
size_t len;
uint8_t stdfd; /* 1 = stdout, 2 = stderr */
/* len bytes of data is overallocated after this */
};
extern struct sai_builder builder;
extern const lws_ss_info_t ssi_sai_builder, ssi_sai_mirror, ssi_sai_artifact;
extern const struct lws_protocols protocol_com_warmcat_sai;
int
saib_config_global(struct sai_builder *builder, const char *d);
extern int saib_config(struct sai_builder *builder, const char *d);
extern void saib_config_destroy(struct sai_builder *builder);
int
saib_overlay_mount(struct sai_builder *b, struct sai_nspawn *ns);
int
saib_overlay_unmount(struct sai_nspawn *ns);
int
saib_spawn_script(struct sai_nspawn *ns);
int
saib_prepare_mount(struct sai_builder *b, struct sai_nspawn *ns);
int
saib_ws_json_rx_builder(struct sai_plat_server *spm, const void *in, size_t len);
int
saib_generate(struct sai_plat *sp, char *buf, int len);
enum lws_threadpool_task_return
saib_mirror_task(void *user, enum lws_threadpool_task_status s);
int
saib_set_ns_state(struct sai_nspawn *ns, int state);
void
saib_task_destroy(struct sai_nspawn *ns);
void
saib_task_grace(struct sai_nspawn *ns);
int
saib_log_chunk_create(struct sai_nspawn *ns, void *buf, size_t len, int channel);
int
rm_rf_cb(const char *dirpath, void *user, struct lws_dir_entry *lde);
extern const struct lws_protocols protocol_logproxy, protocol_resproxy;
void *
saib_thread_suspend(void *d);
int
saib_create_resproxy_listen_uds(struct lws_context *context,
struct sai_plat_server *spm);
int
saib_handle_resource_result(struct sai_plat_server *spm, const char *in, size_t len);
void
saib_sul_load_report_cb(struct lws_sorted_usec_list *sul);
int
saib_get_cgroup_cpu(struct sai_nspawn *ns);
int
saib_get_system_cpu(struct sai_builder *b);
int saib_get_cpu_count(void);
unsigned int
saib_get_free_ram_kib(void);
unsigned int
saib_get_total_ram_kib(void);
unsigned int
saib_get_free_disk_kib(const char *path);
unsigned int
saib_get_total_disk_kib(const char *path);
int
saib_create_listen_uds(struct lws_context *context, struct saib_logproxy *lp, struct lws_vhost **);
int
saib_srv_queue_tx(struct lws_ss_handle *h, void *buf, size_t len, unsigned int ss_flags);
int
saib_srv_queue_json_fragments_helper(struct lws_ss_handle *h,
const lws_struct_map_t *map,
size_t map_entries, void *object);
int
saib_queue_task_status_update(sai_plat_t *sp, struct sai_plat_server *spm,
const char *rej_task_uuid, unsigned int ecode,
unsigned int reason);
int
saib_consider_allocating_task(struct sai_plat_server *spm, lws_struct_args_t *a,
const uint8_t *in, size_t len, int flags);
void
saib_sul_task_cancel(struct lws_sorted_usec_list *sul);
int
saib_suspender_get_pipe(void);
extern int
saib_suspender_fork(const char *path);
extern int
sai_deletion_worker(const char *home_dir);
extern int
saib_suspender_start(void);
extern int
saib_power_init(void);
extern int
saib_deletion_init(const char *argv0);
extern void
suspender_destroy(void);
int
saib_deletion_free_kib(unsigned int needed_kib);
int
saib_reassess_idle_situation(void);
extern int interrupted;
int
saib_app_run(int argc, const char **argv);
void
saib_app_stop(void);
#if defined(__APPLE__)
int
saib_need_wakelock(void);
void
sul_release_wakelock_cb(lws_sorted_usec_list_t *sul);
void
saib_wakelock(void);
#endif
|