void sigusr1_handler(int signo) { int res, i; TRACE_ENTRY(); TRACE_MGMT_DBG("%s", "Capacity data changed..."); for (i = 0; i < num_devs; i++) { res = ioctl(devs[i].scst_usr_fd, SCST_USER_DEVICE_CAPACITY_CHANGED, NULL); if (res != 0) { res = errno; PRINT_ERROR("Capacity data changed failed: %s", strerror(res)); goto out; } } TRACE_DBG("%s", "Capacity data changed done."); out: TRACE_EXIT(); return; }
static int stpg_event_loop(void) { int res = 0, status; int event_fd; uint8_t event_user_buf[1024*1024]; pid_t c_pid = 0; struct pollfd pl; struct scst_event_user *event_user = (struct scst_event_user *)event_user_buf; struct scst_event e1; bool first_error = true; event_fd = open(SCST_EVENT_DEV, O_RDWR); if (event_fd < 0) { res = -errno; PRINT_ERROR("Unable to open SCST event device %s (%s)", SCST_EVENT_DEV, strerror(-res)); goto out; } close(stpg_init_report_pipe[0]); if (log_daemon) res = write(stpg_init_report_pipe[1], &res, sizeof(res)); close(stpg_init_report_pipe[1]); memset(&pl, 0, sizeof(pl)); pl.fd = event_fd; pl.events = POLLIN; memset(&e1, 0, sizeof(e1)); e1.event_code = SCST_EVENT_STPG_USER_INVOKE; strncpy(e1.issuer_name, SCST_EVENT_SCST_CORE_ISSUER, sizeof(e1.issuer_name)); e1.issuer_name[sizeof(e1.issuer_name)-1] = '\0'; PRINT_INFO("Setting allowed event code %d, issuer_name %s", e1.event_code, e1.issuer_name); res = ioctl(event_fd, SCST_EVENT_ALLOW_EVENT, &e1); if (res != 0) { res = -errno; PRINT_ERROR("SCST_EVENT_ALLOW_EVENT failed: %d (%s)", res, strerror(-res)); goto out; } e1.event_code = SCST_EVENT_TM_FN_RECEIVED; strncpy(e1.issuer_name, SCST_EVENT_SCST_CORE_ISSUER, sizeof(e1.issuer_name)); e1.issuer_name[sizeof(e1.issuer_name)-1] = '\0'; PRINT_INFO("Setting allowed event code %d, issuer_name %s", e1.event_code, e1.issuer_name); res = ioctl(event_fd, SCST_EVENT_ALLOW_EVENT, &e1); if (res != 0) { res = -errno; PRINT_ERROR("SCST_EVENT_ALLOW_EVENT failed: %d (%s)", res, strerror(-res)); goto out; } while (1) { memset(event_user_buf, 0, sizeof(event_user_buf)); event_user->max_event_size = sizeof(event_user_buf); res = ioctl(event_fd, SCST_EVENT_GET_NEXT_EVENT, event_user); if (res != 0) { res = -errno; switch (-res) { case ESRCH: case EBUSY: TRACE_MGMT_DBG("SCST_EVENT_GET_NEXT_EVENT " "returned %d (%s)", res, strerror(res)); /* go through */ case EINTR: continue; case EAGAIN: TRACE_DBG("SCST_EVENT_GET_NEXT_EVENT, " "returned EAGAIN (%d)", -res); continue; default: PRINT_ERROR("SCST_EVENT_GET_NEXT_EVENT " "failed: %d (%s)", res, strerror(-res)); if (!first_error) goto out; first_error = false; continue; } first_error = true; again_poll: res = poll(&pl, 1, c_pid > 0 ? 1 : 0); if (res > 0) continue; else if (res == 0) goto again_poll; else { res = -errno; switch (res) { case ESRCH: case EBUSY: case EAGAIN: TRACE_MGMT_DBG("poll() returned %d " "(%s)", res, strerror(-res)); case EINTR: goto again_poll; default: PRINT_ERROR("poll() failed: %d (%s)", res, strerror(-res)); goto again_poll; } } } first_error = true; #ifdef DEBUG PRINT_INFO("event_code %d, issuer_name %s", event_user->out_event.event_code, event_user->out_event.issuer_name); #endif if (event_user->out_event.payload_len != 0) TRACE_BUFFER("payload", event_user->out_event.payload, event_user->out_event.payload_len); if (event_user->out_event.event_code == SCST_EVENT_STPG_USER_INVOKE) { c_pid = fork(); if (c_pid == -1) PRINT_ERROR("Failed to fork: %d", c_pid); else if (c_pid == 0) { struct scst_event_notify_done d; signal(SIGCHLD, SIG_DFL); status = handle_stpg_received(event_user); memset(&d, 0, sizeof(d)); d.event_id = event_user->out_event.event_id; d.status = status; res = ioctl(event_fd, SCST_EVENT_NOTIFY_DONE, &d); if (res != 0) { res = -errno; PRINT_ERROR("SCST_EVENT_NOTIFY_DONE " "failed: %s (res %d)", strerror(-res), res); } else PRINT_INFO("STPG event completed with status %d", status); exit(res); } } else if (event_user->out_event.event_code == SCST_EVENT_TM_FN_RECEIVED) stpg_handle_tm_received(event_user); else PRINT_ERROR("Unknown event %d received", event_user->out_event.event_code); } out: return res; }