// this is the monitor for glob patterns void uwsgi_imperial_monitor_glob(struct uwsgi_emperor_scanner *ues) { glob_t g; int i; struct stat st; struct uwsgi_instance *ui_current; if (glob(ues->arg, GLOB_MARK | GLOB_NOCHECK, NULL, &g)) { uwsgi_error("glob()"); return; } for (i = 0; i < (int) g.gl_pathc; i++) { if (!uwsgi_emperor_is_valid(g.gl_pathv[i])) continue; if (stat(g.gl_pathv[i], &st)) continue; if (!S_ISREG(st.st_mode)) continue; ui_current = emperor_get(g.gl_pathv[i]); if (ui_current) { // check if uid or gid are changed, in such case, stop the instance if (uwsgi.emperor_tyrant) { if (st.st_uid != ui_current->uid || st.st_gid != ui_current->gid) { uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n", g.gl_pathv[i]); emperor_stop(ui_current); continue; } } // check if mtime is changed and the uWSGI instance must be reloaded if (st.st_mtime > ui_current->last_mod) { emperor_respawn(ui_current, st.st_mtime); } } else { emperor_add(ues, g.gl_pathv[i], st.st_mtime, NULL, 0, st.st_uid, st.st_gid); } } globfree(&g); // now check for removed instances struct uwsgi_instance *c_ui = ui->ui_next; while (c_ui) { if (c_ui->scanner == ues) { if (stat(c_ui->name, &st)) { emperor_stop(c_ui); } } c_ui = c_ui->ui_next; } }
void uwsgi_emperor_simple_do(struct uwsgi_emperor_scanner *ues, char *name, char *config, time_t ts, uid_t uid, gid_t gid) { if (!uwsgi_emperor_is_valid(name)) return; struct uwsgi_instance *ui_current = emperor_get(name); if (ui_current) { // check if uid or gid are changed, in such case, stop the instance if (uwsgi.emperor_tyrant) { if (uid != ui_current->uid || gid != ui_current->gid) { uwsgi_log("[emperor-tyrant] !!! permissions of vassal %s changed. stopping the instance... !!!\n", name); emperor_stop(ui_current); return; } } // check if mtime is changed and the uWSGI instance must be reloaded if (ts > ui_current->last_mod) { // make a new config (free the old one) free(ui_current->config); ui_current->config = config; ui_current->config_len = strlen(config); // always respawn (no need for amqp-style rules) emperor_respawn(ui_current, ts); } } else { // make a copy of the config as it will be freed emperor_add(ues, name, ts, uwsgi_str(config), strlen((const char *) config), uid, gid); } }
// this is the monitor for non-glob directories void uwsgi_imperial_monitor_directory(struct uwsgi_emperor_scanner *ues) { struct uwsgi_instance *ui_current; struct dirent *de; struct stat st; if (chdir(ues->arg)) { uwsgi_error("chdir()"); return; } DIR *dir = opendir("."); while ((de = readdir(dir)) != NULL) { if (!uwsgi_emperor_is_valid(de->d_name)) continue; if (stat(de->d_name, &st)) continue; if (!S_ISREG(st.st_mode)) continue; ui_current = emperor_get(de->d_name); if (ui_current) { // check if uid or gid are changed, in such case, stop the instance if (uwsgi.emperor_tyrant) { if (st.st_uid != ui_current->uid || st.st_gid != ui_current->gid) { uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n", de->d_name); emperor_stop(ui_current); continue; } } // check if mtime is changed and the uWSGI instance must be reloaded if (st.st_mtime > ui_current->last_mod) { emperor_respawn(ui_current, st.st_mtime); } } else { emperor_add(ues, de->d_name, st.st_mtime, NULL, 0, st.st_uid, st.st_gid); } } closedir(dir); // now check for removed instances struct uwsgi_instance *c_ui = ui->ui_next; while (c_ui) { if (c_ui->scanner == ues) { if (stat(c_ui->name, &st)) { emperor_stop(c_ui); } } c_ui = c_ui->ui_next; } }
void uwsgi_emperor_simple_do(struct uwsgi_emperor_scanner *ues, char *name, char *config, time_t ts, uid_t uid, gid_t gid, char *socket_name) { if (!uwsgi_emperor_is_valid(name)) return; struct uwsgi_instance *ui_current = emperor_get(name); if (ui_current) { // check if uid or gid are changed, in such case, stop the instance if (uwsgi.emperor_tyrant) { if (uid != ui_current->uid || gid != ui_current->gid) { uwsgi_log("[emperor-tyrant] !!! permissions of vassal %s changed. stopping the instance... !!!\n", name); emperor_stop(ui_current); return; } } // check if mtime is changed and the uWSGI instance must be reloaded if (ts > ui_current->last_mod) { // make a new config (free the old one) if needed if (config) { if (ui_current->config) free(ui_current->config); ui_current->config = uwsgi_str(config); ui_current->config_len = strlen(ui_current->config); } // reload the instance emperor_respawn(ui_current, ts); } } else { // make a copy of the config as it will be freed char *new_config = NULL; size_t new_config_len = 0; if (config) { new_config = uwsgi_str(config); new_config_len = strlen(new_config); } emperor_add(ues, name, ts, new_config, new_config_len, uid, gid, socket_name); } }
// this is the monitor for glob patterns void uwsgi_imperial_monitor_glob(struct uwsgi_emperor_scanner *ues) { glob_t g; int i; struct stat st; struct uwsgi_instance *ui_current; if (glob(ues->arg, GLOB_MARK | GLOB_NOCHECK, NULL, &g)) { uwsgi_error("glob()"); return; } for (i = 0; i < (int) g.gl_pathc; i++) { if (!uwsgi_emperor_is_valid(g.gl_pathv[i])) continue; if (stat(g.gl_pathv[i], &st)) continue; if (!S_ISREG(st.st_mode)) continue; ui_current = emperor_get(g.gl_pathv[i]); uid_t t_uid = st.st_uid; gid_t t_gid = st.st_gid; if (uwsgi.emperor_tyrant && uwsgi.emperor_tyrant_nofollow) { struct stat lst; if (lstat(g.gl_pathv[i], &lst)) { uwsgi_error("[emperor-tyrant]/lstat()"); if (ui_current) { uwsgi_log("!!! availability of file %s changed. stopping the instance... !!!\n", g.gl_pathv[i]); emperor_stop(ui_current); } continue; } t_uid = lst.st_uid; t_gid = lst.st_gid; } if (ui_current) { // check if uid or gid are changed, in such case, stop the instance if (uwsgi.emperor_tyrant) { if (t_uid != ui_current->uid || t_gid != ui_current->gid) { uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n", g.gl_pathv[i]); emperor_stop(ui_current); continue; } } // check if mtime is changed and the uWSGI instance must be reloaded if (st.st_mtime > ui_current->last_mod) { emperor_respawn(ui_current, st.st_mtime); } } else { char *socket_name = emperor_check_on_demand_socket(g.gl_pathv[i]); emperor_add(ues, g.gl_pathv[i], st.st_mtime, NULL, 0, t_uid, t_gid, socket_name); if (socket_name) free(socket_name); } } globfree(&g); // now check for removed instances struct uwsgi_instance *c_ui = ui->ui_next; while (c_ui) { if (c_ui->scanner == ues) { if (c_ui->zerg) { char *colon = strrchr(c_ui->name, ':'); if (!colon) { emperor_stop(c_ui); } else { char *filename = uwsgi_calloc(0xff); memcpy(filename, c_ui->name, colon - c_ui->name); if (stat(filename, &st)) { emperor_stop(c_ui); } free(filename); } } else { if (stat(c_ui->name, &st)) { emperor_stop(c_ui); } } } c_ui = c_ui->ui_next; } }
// this is the monitor for non-glob directories void uwsgi_imperial_monitor_directory(struct uwsgi_emperor_scanner *ues) { struct uwsgi_instance *ui_current; struct dirent *de; struct stat st; if (chdir(ues->arg)) { uwsgi_error("chdir()"); return; } DIR *dir = opendir("."); while ((de = readdir(dir)) != NULL) { if (!uwsgi_emperor_is_valid(de->d_name)) continue; if (stat(de->d_name, &st)) continue; if (!S_ISREG(st.st_mode)) continue; ui_current = emperor_get(de->d_name); uid_t t_uid = st.st_uid; gid_t t_gid = st.st_gid; if (uwsgi.emperor_tyrant && uwsgi.emperor_tyrant_nofollow) { struct stat lst; if (lstat(de->d_name, &lst)) { uwsgi_error("[emperor-tyrant]/lstat()"); if (ui_current) { uwsgi_log("!!! availability of file %s changed. stopping the instance... !!!\n", de->d_name); emperor_stop(ui_current); } continue; } t_uid = lst.st_uid; t_gid = lst.st_gid; } if (ui_current) { // check if uid or gid are changed, in such case, stop the instance if (uwsgi.emperor_tyrant) { if (t_uid != ui_current->uid || t_gid != ui_current->gid) { uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n", de->d_name); emperor_stop(ui_current); continue; } } // check if mtime is changed and the uWSGI instance must be reloaded if (st.st_mtime > ui_current->last_mod) { emperor_respawn(ui_current, st.st_mtime); } } else { char *socket_name = emperor_check_on_demand_socket(de->d_name); emperor_add(ues, de->d_name, st.st_mtime, NULL, 0, t_uid, t_gid, socket_name); if (socket_name) free(socket_name); } } closedir(dir); // now check for removed instances struct uwsgi_instance *c_ui = ui->ui_next; while (c_ui) { if (c_ui->scanner == ues) { if (c_ui->zerg) { char *colon = strrchr(c_ui->name, ':'); if (!colon) { emperor_stop(c_ui); } else { char *filename = uwsgi_calloc(0xff); memcpy(filename, c_ui->name, colon - c_ui->name); if (stat(filename, &st)) { emperor_stop(c_ui); } free(filename); } } else { if (stat(c_ui->name, &st)) { emperor_stop(c_ui); } } } c_ui = c_ui->ui_next; } }