/* mounts the firmware so that the client can retrieve informations if needed */ static int mount_firmware(struct firmware *firmware) { int ret; int ret2; struct io_process process; const char *mount_dir = folder_entity_get_base_workspace(&firmware->entity); ret = mkdir(mount_dir, 0755); if (ret == -1 && errno != EEXIST) ULOGW("mkdir: %m"); if (ut_file_is_dir(firmware->path)) { ret = io_process_init_prepare_launch_and_wait(&process, &process_default_parameters, NULL, "/bin/mount", "--bind", firmware->path, mount_dir, NULL); /* * The remount is necessary to make this bind mount read-only. * Trying to pass the ro option directly to the previous command * won't work, according to the man page, the mount options of * the bind mount will be the same as those of the original * mount. */ ret2 = io_process_init_prepare_launch_and_wait(&process, &process_default_parameters, NULL, "/bin/mount", "-o", "ro,remount,bind", firmware->path, mount_dir, NULL); if (ret2 < 0) ULOGW("remounting %s read-only failed: %s", mount_dir, strerror(-ret2)); } else { ret = io_process_init_prepare_launch_and_wait(&process, &process_default_parameters, NULL, "/bin/mount", "-o", "ro,loop", firmware->path, mount_dir, NULL); } return ret; }
static struct firmware *firmware_new(const char *path) { int ret; const char *sha1; struct firmware *firmware; const char *firmware_repository_path = config_get(CONFIG_REPOSITORY_PATH); ULOGD("indexing firmware %s", path); firmware = calloc(1, sizeof(*firmware)); if (firmware == NULL) return NULL; firmware->entity.folder = folder_find(FIRMWARES_FOLDER_NAME); if (ut_file_is_dir(path)) { firmware->path = realpath(path, NULL); if (firmware->path == NULL) { ret = -errno; ULOGE("strdup: %m"); goto err; } ULOGI("real path is %s", firmware->path); } else { ret = asprintf(&firmware->path, "%s/%s", firmware_repository_path, path); if (ret == -1) { firmware->path = NULL; ULOGE("asprintf error"); errno = -ENOMEM; goto err; } } /* force sha1 computation while in parallel section */ sha1 = compute_sha1(firmware); if (sha1 == NULL) goto err; ret = mount_firmware(firmware); if (ret < 0) ULOGW("read_firmware_info failed: %s\n", strerror(-ret)); ULOGD("indexing firmware %s done", path); return firmware; err: firmware_delete(&firmware); return NULL; }
static void preparation_progress_sep_cb(struct io_src_sep *sep, char *chunk, unsigned len) { int ret; struct firmware_preparation *firmware_preparation; struct preparation *preparation; struct io_process *process; if (len == 0) return; process = ut_container_of(sep, struct io_process, stdout_src); firmware_preparation = ut_container_of(process, struct firmware_preparation, process); preparation = &firmware_preparation->preparation; chunk[len] = '\0'; ut_string_rstrip(chunk); ULOGD("%s "FIRMWARES_FOLDER_NAME" preparation %s", preparation->identification_string, chunk); /* * rearm the "watch dog", we don't want to abort a working dl because it * took too long */ ret = io_process_set_timeout(process, PREPARATION_TIMEOUT, PREPARATION_TIMEOUT_SIGNAL); if (ret < 0) ULOGW("resetting firmware preparation timeout failed: %s", strerror(-ret)); if (ut_string_match_prefix(chunk, "destination_file=")) { firmware_preparation->destination_file = strdup(chunk + 17); /* * here the hook is stuck in a sleep, waiting for us to say it * it can nicely die */ io_process_signal(process, SIGUSR1); } else { ret = firmwared_notify(FWD_ANSWER_PREPARE_PROGRESS, FWD_FORMAT_ANSWER_PREPARE_PROGRESS, preparation->seqnum, preparation->folder, preparation->identification_string, chunk); if (ret < 0) ULOGE("firmwared_notify: %s", strerror(-ret)); } }
int folders_reap_preparations(void) { int ret; struct folder *folder; int i; for (i = 0; i < FOLDERS_MAX; i++) { folder = folders + i; if (folder->name == NULL) continue; if (rs_dll_get_count(&folder->preparations) == 0) continue; ret = folder_reap_preparations_of_folder(folder); if (ret < 0) ULOGW("folder_reap_preparations_of_folder: %s", strerror(-ret)); } return 0; }
static int entity_completion(struct preparation *preparation, struct folder_entity *entity) { struct folder *folder; int ret = 0; if (entity == NULL) { ULOGW("%*s creation failed for identification string %s", (int)strlen(preparation->folder) - 1, preparation->folder, preparation->identification_string); ret = -EINVAL; goto out; } /* if already prepared, nothing to be done */ folder = folder_find(preparation->folder); if (find_entity(folder, folder_entity_get_sha1(entity))) goto out; /* folder_store transfers the ownership of the entity to the folder */ ret = folder_store(preparation->folder, entity); if (ret < 0) { do_drop(entity, false); ULOGE("folder_store: %s", strerror(-ret)); goto out; } ret = 0; out: if (ret >= 0) firmwared_notify(FWD_ANSWER_PREPARED, FWD_FORMAT_ANSWER_PREPARED, preparation->seqnum, preparation->folder, folder_entity_get_sha1(entity), entity->name); preparation->has_ended = true; return ret; }
static void client_event_cb(struct pomp_ctx *ctx, enum pomp_event event, struct pomp_conn *conn, const struct pomp_msg *msg, void *userdata) { int fd, msgid; unsigned int bufsize; void *video_buffer; GstVideoFormat videoformat; unsigned int width, height; switch (event) { case POMP_EVENT_CONNECTED: ULOGI("connected to pimp user filter"); break; case POMP_EVENT_DISCONNECTED: ULOGI("disconnected from pimp user filter"); break; case POMP_EVENT_MSG: switch (msgid = pomp_msg_get_id(msg)) { case SEND_FD: pomp_msg_read(msg, "%x%u%u%u%u", &fd, &bufsize, &videoformat, &width, &height); ULOGI("received a FD from pimp: %d", fd); video_buffer = mmap(NULL, bufsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); s_app.process(video_buffer, bufsize, videoformat, width, height, s_app.priv); pomp_ctx_send(ctx, BUFFER_PROCESSING_DONE, NULL); break; default: ULOGW("received unknown message id from pimp : %d", msgid); break; } break; default: ULOGE("Unknown event: %d", event); break; } }