X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=afs.c;h=eb18708c5742ff8e5c603ba9bf05efca5bace21d;hp=f76da3dc17a398e2b273ec3a12b5b166520b6d56;hb=23b121a85984baa9252f4b4c0b8c4f186e394bb7;hpb=d5a9e8c8eefe170b6fb62be563c079c818bd3bf8 diff --git a/afs.c b/afs.c index f76da3dc..eb18708c 100644 --- a/afs.c +++ b/afs.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2012 Andre Noll + * Copyright (C) 2007-2013 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -87,7 +87,7 @@ static struct command_task command_task_struct; static struct signal_task signal_task_struct; static enum play_mode current_play_mode; -static char *current_mop; /* mode or playlist specifier. NULL means dummy mooe */ +static char *current_mop; /* mode or playlist specifier. NULL means dummy mood */ /** * A random number used to "authenticate" the connection. @@ -113,7 +113,7 @@ extern uint32_t afs_socket_cookie; * area is written to the command socket. * * The afs process accepts connections on the command socket and reads the - * shared memory id, attaches the corresponing area, calls the given handler to + * shared memory id, attaches the corresponding area, calls the given handler to * perform the desired action and to optionally compute a result. * * The result and a \p callback_result structure is then written to another @@ -133,7 +133,7 @@ struct callback_query { /** * Structure embedded in the result of a callback. * - * If the callback produced a result, an instance of that structure is embeeded + * If the callback produced a result, an instance of that structure is embedded * into the shared memory area holding the result, mainly to let the command * handler know the size of the result. * @@ -142,6 +142,8 @@ struct callback_query { struct callback_result { /** The number of bytes of the result. */ size_t result_size; + /** The band designator (loglevel for the result). */ + uint8_t band; }; static int dispatch_result(int result_shmid, callback_result_handler *handler, @@ -149,7 +151,8 @@ static int dispatch_result(int result_shmid, callback_result_handler *handler, { struct osl_object result; void *result_shm; - int ret2, ret = shm_attach(result_shmid, ATTACH_RO, &result_shm); + /* must attach r/w as result.data might get encrypted in-place. */ + int ret2, ret = shm_attach(result_shmid, ATTACH_RW, &result_shm); struct callback_result *cr = result_shm; if (ret < 0) { @@ -160,7 +163,7 @@ static int dispatch_result(int result_shmid, callback_result_handler *handler, result.data = result_shm + sizeof(*cr); if (result.size) { assert(handler); - ret = handler(&result, private_result_data); + ret = handler(&result, cr->band, private_result_data); if (ret < 0) PARA_NOTICE_LOG("result handler error: %s\n", para_strerror(-ret)); @@ -549,6 +552,7 @@ static void com_select_callback(int fd, const struct osl_object *query) .max_size = shm_get_shmmax(), .private_data = &(struct afs_max_size_handler_data) { .fd = fd, + .band = SBD_OUTPUT }, .max_size_handler = afs_max_size_handler, }; @@ -580,7 +584,7 @@ static void com_select_callback(int fd, const struct osl_object *query) current_mop : "dummy mood", num_admissible); out: if (ret2 >= 0 && pb.offset) - pass_buffer_as_shm(fd, pb.buf, pb.offset); + pass_buffer_as_shm(fd, SBD_OUTPUT, pb.buf, pb.offset); free(pb.buf); } @@ -588,23 +592,25 @@ out: * Result handler for sending data to the para_client process. * * \param result The data to be sent. - * \param private Pointer to the context. + * \param band The band designator. + * \param private Pointer to the command context. * - * \return The return value of the underlying call to sc_send_bin_buffer(). + * \return The return value of the underlying call to \ref command.c::send_sb. * - * \sa \ref callback_result_handler, \ref sc_send_bin_buffer(). + * \sa \ref callback_result_handler, \ref command.c::send_sb. */ -int afs_cb_result_handler(struct osl_object *result, void *private) +int afs_cb_result_handler(struct osl_object *result, uint8_t band, + void *private) { struct command_context *cc = private; - int ret; + assert(cc); if (!result->size) return 1; - ret = sc_send_bin_buffer(&cc->scc, result->data, result->size); - if (ret < 0 || ret == result->size) - return ret; - return -E_SHORT_WRITE; + if (cc->use_sideband) + return send_sb(&cc->scc, result->data, result->size, band, + true); + return sc_send_bin_buffer(&cc->scc, result->data, result->size); } int com_select(struct command_context *cc) @@ -739,7 +745,7 @@ static void afs_signal_post_select(struct sched *s, struct task *t) } PARA_EMERG_LOG("terminating on signal %d\n", signum); shutdown: - sched_shutdown(s); + task_notify_all(s, E_AFS_SIGNAL); t->error = -E_AFS_SIGNAL; } @@ -787,12 +793,13 @@ static void command_pre_select(struct sched *s, struct task *t) * Send data as shared memory to a file descriptor. * * \param fd File descriptor to send the shmid to. + * \param band The band designator for this data. * \param buf The buffer holding the data to be sent. * \param size The size of \a buf. * * This function creates a shared memory area large enough to hold * the content given by \a buf and \a size and sends the identifier - * of this area to the file descriptor given by \a fd_ptr. + * of this area to the file descriptor \a fd. * * It is called by the AFS max_size handler as well as directly by the AFS * command callbacks to send command output to the command handlers. @@ -800,7 +807,7 @@ static void command_pre_select(struct sched *s, struct task *t) * \return Zero if \a buf is \p NULL or \a size is zero. Negative on errors, * and positive on success. */ -int pass_buffer_as_shm(int fd, char *buf, size_t size) +int pass_buffer_as_shm(int fd, uint8_t band, char *buf, size_t size) { int ret, shmid; void *shm; @@ -808,7 +815,7 @@ int pass_buffer_as_shm(int fd, char *buf, size_t size) if (!buf || !size) return 0; - ret = shm_new(size + sizeof(struct callback_result)); + ret = shm_new(size + sizeof(*cr)); if (ret < 0) return ret; shmid = ret; @@ -817,6 +824,7 @@ int pass_buffer_as_shm(int fd, char *buf, size_t size) goto err; cr = shm; cr->result_size = size; + cr->band = band; memcpy(shm + sizeof(*cr), buf, size); ret = shm_detach(shm); if (ret < 0) @@ -914,10 +922,16 @@ static void command_post_select(struct sched *s, struct task *t) struct afs_client *client, *tmp; int fd, ret; + ret = task_get_notification(t); + if (ret < 0) { + t->error = ret; + return; + } ret = execute_server_command(&s->rfds); if (ret < 0) { PARA_EMERG_LOG("%s\n", para_strerror(-ret)); - sched_shutdown(s); + task_notify_all(s, -ret); + t->error = ret; return; } /* Check the list of connected clients. */ @@ -1025,7 +1039,7 @@ out: if (ret < 0) para_printf(&pb, "%s\n", para_strerror(-ret)); if (pb.buf) - pass_buffer_as_shm(fd, pb.buf, pb.offset); + pass_buffer_as_shm(fd, SBD_OUTPUT, pb.buf, pb.offset); free(pb.buf); } @@ -1056,7 +1070,7 @@ int com_init(struct command_context *cc) } ret = send_callback_request(create_tables_callback, &query, afs_cb_result_handler, cc); - if (ret < 0) + if (ret < 0 && !cc->use_sideband) /* ignore return value */ sc_send_va_buffer(&cc->scc, "%s\n", para_strerror(-ret)); return ret;