failure INVALID_ID "Invalid Trigger ID.",
failure CAP_NAME_UNKNOWN "Capability storage: Unknown name.",
failure CAP_OVERWRITE "Capability storage: Cap already exists.",
+ failure IDCAP_INVOKE "Error invoking ID capability.",
};
// kaluga library errors
/*
- * Copyright (c) 2007, 2008, 2009, ETH Zurich.
+ * Copyright (c) 2007, 2008, 2009, 2012, ETH Zurich.
* All rights reserved.
*
* This file is distributed under the terms in the attached LICENSE file.
* If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
+ * Attn: Systems Group.
*/
interface octopus "octopus RPC Interface" {
* \param tid Id of registered trigger (0 in case no trigger registered).
* \param error_code Error value of request.
*/
- rpc get_names(in string query, in trigger t, out string output, out trigger_id tid, out errval error_code);
+ rpc get_names(in string query, in trigger t, out string output,
+ out trigger_id tid, out errval error_code);
/**
* \param query Record to find.
* \param tid Id of registered trigger (0 in case no trigger registered).
* \param error_code Error value of request.
*/
- rpc get(in string query, in trigger t, out string output, out trigger_id tid, out errval error_code);
+ rpc get(in string query, in trigger t, out string output,
+ out trigger_id tid, out errval error_code);
/**
* \param query Record to set.
* \param tid Id of registered trigger (0 in case no trigger registered).
* \param error_code Error value of request
*/
- rpc set(in string query, in uint64 mode, in trigger t, in bool get, out string record, out trigger_id tid, out errval error_code);
+ rpc set(in string query, in uint64 mode, in trigger t, in bool get,
+ out string record, out trigger_id tid, out errval error_code);
+
+ /**
+ * Find a record using an ID capability as the key/name of the record.
+ *
+ * \param idcap ID capability used as the name of the record.
+ * \param t Additional trigger to watch for future events.
+ * \param output Retrieved record or NULL on error.
+ * \param tid Id of registered trigger (0 in case no trigger registered).
+ * \param error_code Error value of request.
+ */
+ rpc get_with_idcap(in cap idcap, in trigger t, out string output,
+ out trigger_id tid, out errval error_code);
+
+ /**
+ * Set a record using an ID capability as the key/name of the record.
+ *
+ * \param idcap ID capability used as the key/name of the record.
+ * \param attributes Attributes to store in the record.
+ * \param mode Set mode (see getset.h).
+ * \param t Additional trigger to watch for future events.
+ * \param get Return record if it has been set.
+ * \param record In case get is true and no error_code is ok
+ * contains record, otherwise NULL
+ * \param tid Id of registered trigger (0 in case no trigger registered).
+ * \param error_code Error value of request
+ */
+ rpc set_with_idcap(in cap idcap, in string attributes, in uint64 mode,
+ in trigger t, in bool get, out string record,
+ out trigger_id tid, out errval error_code);
/**
* \param query Record(s) to delete.
* \param tid Id of registered trigger (0 in case no trigger registered).
* \param error_code Error value of request
*/
- rpc del(in string query, in trigger t, out trigger_id tid, out errval error_code);
+ rpc del(in string query, in trigger t, out trigger_id tid,
+ out errval error_code);
/**
* \param query
* \param tid Id of registered trigger (0 in case no trigger registered).
* \param error_code Error value of request.
*/
- rpc exists(in string query, in trigger t, out trigger_id tid, out errval error_code);
+ rpc exists(in string query, in trigger t, out trigger_id tid,
+ out errval error_code);
/**
* \brief Blocks until a record matching the provided query is registered.
* \param id Identifier for this subscription supplied by server.
* \param error_code Status of request.
*/
- rpc subscribe(in string query, in uint64 trigger_fn, in uint64 state, out uint64 id, out errval error_code);
+ rpc subscribe(in string query, in uint64 trigger_fn, in uint64 state,
+ out uint64 id, out errval error_code);
/**
* \param id Id for the subscription
//
// Async events (sent by server to client)
//
- message trigger(trigger_id id, uint64 trigger_fn, mode m, string record, uint64 state);
- message subscription(trigger_id id, uint64 trigger_fn, mode m, string record, uint64 state);
+ message trigger(trigger_id id, uint64 trigger_fn, mode m, string record,
+ uint64 state);
+
+ message subscription(trigger_id id, uint64 trigger_fn, mode m,
+ string record, uint64 state);
//
errval_t oct_get(char**, const char*, ...);
errval_t oct_set(const char*, ...);
+errval_t oct_get_with_idcap(char**, struct capref);
+errval_t oct_set_with_idcap(struct capref, const char*, ...);
errval_t oct_mset(oct_mode_t, const char*, ...);
errval_t oct_set_get(oct_mode_t, char**, const char*, ...);
errval_t oct_del(const char*, ...);
*/
/*
- * Copyright (c) 2011, ETH Zurich.
+ * Copyright (c) 2011, 2012, ETH Zurich.
* All rights reserved.
*
* This file is distributed under the terms in the attached LICENSE file.
* If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
+ * Attn: Systems Group.
*/
#ifndef OCTOPUS_SERVICE_H_
void get_names_handler(struct octopus_binding*, char*, octopus_trigger_t);
void get_handler(struct octopus_binding*, char*, octopus_trigger_t);
void set_handler(struct octopus_binding*, char*, uint64_t, octopus_trigger_t, bool);
+void get_with_idcap_handler(struct octopus_binding*, struct capref,
+ octopus_trigger_t);
+void set_with_idcap_handler(struct octopus_binding*, struct capref, char*,
+ uint64_t, octopus_trigger_t, bool);
void del_handler(struct octopus_binding*, char*, octopus_trigger_t);
void exists_handler(struct octopus_binding*, char*, octopus_trigger_t);
void wait_for_handler(struct octopus_binding*, char*);
*/
/*
- * Copyright (c) 2011, ETH Zurich.
+ * Copyright (c) 2011, 2012, ETH Zurich.
* All rights reserved.
*
* This file is distributed under the terms in the attached LICENSE file.
* If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
+ * Attn: Systems Group.
*/
#include <stdlib.h>
}
/**
+ * \brief Gets one record using the ID capability as the key/name.
+ *
+ * \param[out] data Record returned by the server.
+ * \param[in] idcap ID capability used as the key/name of the record.
+ *
+ * \retval SYS_ERR_OK
+ * \retval OCT_ERR_NO_RECORD
+ * \retval OCT_ERR_PARSER_FAIL
+ * \retval OCT_ERR_ENGINE_FAIL
+ */
+errval_t oct_get_with_idcap(char **data, struct capref idcap)
+{
+ assert(!capref_is_null(idcap));
+ errval_t error_code;
+ errval_t err = SYS_ERR_OK;
+ octopus_trigger_id_t tid;
+
+ struct octopus_thc_client_binding_t *cl = oct_get_thc_client();
+ assert(cl != NULL);
+ err = cl->call_seq.get_with_idcap(cl, idcap, NOP_TRIGGER, data, &tid,
+ &error_code);
+
+ if (err_is_ok(err)) {
+ err = error_code;
+ }
+
+ return err;
+}
+
+/**
+ * \brief Sets a record using the ID capability as the name/key of the record.
+ *
+ * \param idcap ID capability used as the name/key of the record.
+ * \param attributes Attributes of the record.
+ * \param ... Additional arguments to format the attributes using
+ * vsprintf.
+ *
+ * \retval SYS_ERR_OK
+ * \retval OCT_ERR_NO_RECORD_NAME
+ * \retval OCT_ERR_PARSER_FAIL
+ * \retval OCT_ERR_ENGINE_FAIL
+ */
+errval_t oct_set_with_idcap(struct capref idcap, const char *attributes, ...)
+{
+ assert(!capref_is_null(idcap));
+ assert(attributes != NULL);
+ errval_t err = SYS_ERR_OK;
+ va_list args;
+
+ char *buf = NULL;
+ FORMAT_QUERY(attributes, args, buf);
+
+ // Send to Server
+ struct octopus_thc_client_binding_t *cl = oct_get_thc_client();
+
+ char *record = NULL;
+ errval_t error_code;
+ octopus_trigger_id_t tid;
+ err = cl->call_seq.set_with_idcap(cl, idcap, buf, SET_DEFAULT, NOP_TRIGGER,
+ false, &record, &tid, &error_code);
+ assert(record == NULL);
+
+ if (err_is_ok(err)) {
+ err = error_code;
+ }
+
+ free(buf);
+ return err;
+}
+
+/**
* \brief Deletes all records matching the given query.
*
* \param query Specifies the record(s) to be deleted.
*/
/*
- * Copyright (c) 2011, ETH Zurich.
+ * Copyright (c) 2011, 2012, ETH Zurich.
* All rights reserved.
*
* This file is distributed under the terms in the attached LICENSE file.
* If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
+ * Attn: Systems Group.
*/
#include <barrelfish/barrelfish.h>
.get_names_call = get_names_handler,
.get_call = get_handler,
.set_call = set_handler,
+ .get_with_idcap_call = get_with_idcap_handler,
+ .set_with_idcap_call = set_with_idcap_handler,
.del_call = del_handler,
.exists_call = exists_handler,
.wait_for_call = wait_for_handler,
*/
/*
- * Copyright (c) 2009, 2010, ETH Zurich.
+ * Copyright (c) 2009, 2010, 2012, ETH Zurich.
* All rights reserved.
*
* This file is distributed under the terms in the attached LICENSE file.
* If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
+ * Attn: Systems Group.
*/
#include <stdio.h>
#include "queue.h"
+/**
+ * Name prefix used to by the functions set_with_idcap_handler() and
+ * get_with_idcap_handler() to store and retrieve records by idcap.
+ *
+ * This essentially emulates a dedicated namespace for records stored with an
+ * id cap. Octopus and the SKB do not support dedicated namespaces atm.
+ * FIXME: store records set with the function 'set_with_idcap' in a dedicated
+ * namespace.
+ */
+#define IDCAPID_NAME_PREFIX "idcapid."
+
static uint64_t current_id = 1;
static inline errval_t check_query_length(char* query) {
free(query);
}
+static errval_t build_query_with_idcap(char **query_p, struct capref idcap,
+ char *attributes)
+{
+ errval_t err;
+ idcap_id_t id = 0;
+ size_t query_size, bytes_written;
+
+ // retrieve id from idcap
+ err = invoke_idcap_identify(idcap, &id);
+ if (err_is_fail(err)) {
+ return err_push(err, OCT_ERR_IDCAP_INVOKE);
+ }
+ cap_delete(idcap);
+
+ if (attributes == NULL) {
+ attributes = "";
+ }
+
+ // build query using the idcapid and the attributes
+ query_size = snprintf(NULL, 0, IDCAPID_NAME_PREFIX "%" PRIxIDCAPID "%s", id,
+ attributes);
+ *query_p = (char *) malloc(query_size + 1); // include \0
+ if (*query_p == NULL) {
+ return LIB_ERR_MALLOC_FAIL;
+ }
+ bytes_written = snprintf(*query_p, query_size + 1, IDCAPID_NAME_PREFIX
+ "%" PRIxIDCAPID "%s", id, attributes);
+
+ return SYS_ERR_OK;
+}
+
+static void get_with_idcap_reply(struct octopus_binding *b,
+ struct oct_reply_state *drt)
+{
+ errval_t err;
+ char *reply = err_is_ok(drt->error) ?
+ drt->query_state.std_out.buffer : NULL;
+ err = b->tx_vtbl.get_with_idcap_response(b,
+ MKCONT(free_oct_reply_state, drt),
+ reply, drt->server_id, drt->error);
+ if (err_is_fail(err)) {
+ if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
+ oct_rpc_enqueue_reply(b, drt);
+ return;
+ }
+ USER_PANIC_ERR(err, "SKB sending %s failed!", __FUNCTION__);
+ }
+}
+
+void get_with_idcap_handler(struct octopus_binding *b, struct capref idcap,
+ octopus_trigger_t trigger)
+{
+ errval_t err;
+ char *query = NULL;
+ struct oct_reply_state *drs = NULL;
+ struct ast_object *ast = NULL;
+
+ err = build_query_with_idcap(&query, idcap, "");
+ if (err_is_fail(err)) {
+ goto out;
+ }
+
+ OCT_DEBUG("get_with_idcap_handler: %s\n", query);
+
+ err = new_oct_reply_state(&drs, get_with_idcap_reply);
+ assert(err_is_ok(err));
+
+ err = check_query_length(query);
+ if (err_is_fail(err)) {
+ goto out;
+ }
+
+ err = generate_ast(query, &ast);
+ if (err_is_ok(err)) {
+ err = get_record(ast, &drs->query_state);
+ drs->server_id = install_trigger(b, ast, trigger, err);
+ }
+
+out:
+ drs->error = err;
+ drs->reply(b, drs);
+
+ free_ast(ast);
+ if (query != NULL) {
+ free(query);
+ }
+}
+
+static void set_with_idcap_reply(struct octopus_binding *b,
+ struct oct_reply_state *drs)
+{
+ char *record = err_is_ok(drs->error) && drs->return_record ?
+ drs->query_state.std_out.buffer : NULL;
+
+ errval_t err;
+ err = b->tx_vtbl.set_with_idcap_response(b,
+ MKCONT(free_oct_reply_state, drs),
+ record, drs->server_id,
+ drs->error);
+ if (err_is_fail(err)) {
+ if (err_no(err) == FLOUNDER_ERR_TX_BUSY) {
+ oct_rpc_enqueue_reply(b, drs);
+ return;
+ }
+ USER_PANIC_ERR(err, "SKB sending %s failed!", __FUNCTION__);
+ }
+}
+
+void set_with_idcap_handler(struct octopus_binding *b, struct capref idcap,
+ char *attributes, uint64_t mode,
+ octopus_trigger_t trigger, bool get)
+{
+ errval_t err;
+ char *query = NULL;
+ struct oct_reply_state *drs = NULL;
+ struct ast_object *ast = NULL;
+
+ err = build_query_with_idcap(&query, idcap, attributes);
+ if (err_is_fail(err)) {
+ goto out;
+ }
+ OCT_DEBUG(" set_with_idcap_handler: %s\n", query);
+
+ err = new_oct_reply_state(&drs, set_with_idcap_reply);
+ assert(err_is_ok(err));
+
+ err = check_query_length(query);
+ if (err_is_fail(err)) {
+ goto out;
+ }
+
+ err = generate_ast(query, &ast);
+ if (err_is_ok(err)) {
+ if (ast->u.on.name->type == nodeType_Ident) {
+ err = set_record(ast, mode, &drs->query_state);
+ drs->server_id = install_trigger(b, ast, trigger, err);
+ } else {
+ err = OCT_ERR_NO_RECORD_NAME;
+ }
+ }
+
+out:
+ drs->error = err;
+ drs->return_record = get;
+ drs->reply(b, drs);
+
+ free_ast(ast);
+ free(attributes);
+ if (query != NULL) {
+ free(query);
+ }
+
+}
+
static void del_reply(struct octopus_binding* b, struct oct_reply_state* drs)
{
errval_t err;
--------------------------------------------------------------------------
--- Copyright (c) 2007-2011, ETH Zurich.
+-- Copyright (c) 2007-2011, 2012, ETH Zurich.
-- All rights reserved.
--
-- This file is distributed under the terms in the attached LICENSE file.
-- If you do not find this file, copies can be found by writing to:
--- ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+-- ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
+-- Attn: Systems Group.
--
-- Hakefile for /usr/tests/octopus
--
architectures = [ "x86_64", "x86_32" ]
},
+ build application { target = "d2getset_idcap",
+ cFiles = [ "d2getset_idcap.c" ],
+ flounderDefs = [ "octopus" ],
+ flounderBindings = [ "octopus" ],
+ flounderTHCStubs = [ "octopus" ],
+ addLibraries = [ "octopus", "octopus_parser", "thc" ],
+ architectures = [ "x86_64", "x86_32" ]
+ },
+
build application { target = "d2pubsub",
cFiles = [ "d2pubsub.c" ],
flounderDefs = [ "octopus" ],
--- /dev/null
+/**
+ * \file
+ * \brief Tests for octopus get_with_idcap/set_with_idcap API
+ */
+
+/*
+ * Copyright (c) 2012, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
+ * Attn: Systems Group.
+ */
+
+#include <stdio.h>
+
+#include <barrelfish/barrelfish.h>
+#include <octopus/octopus.h>
+
+#include "common.h"
+
+struct capref idcap1, idcap2;
+
+static void set_records(void)
+{
+ errval_t err;
+
+ err = idcap_alloc(&idcap1);
+ ASSERT_ERR_OK(err);
+
+ err = idcap_alloc(&idcap2);
+ ASSERT_ERR_OK(err);
+
+ err = oct_set_with_idcap(idcap1, "{session_iref: %d, io_iref: %d}", 1, 2);
+ if (err_is_fail(err)) {
+ USER_PANIC_ERR(err, "Error installing first record.");
+ }
+ ASSERT_ERR_OK(err);
+
+ err = oct_set_with_idcap(idcap2, "{session_iref: %d, io_iref: %d}", 3, 4);
+ ASSERT_ERR_OK(err);
+}
+
+static void get_records(void)
+{
+ errval_t err;
+
+ char *data = NULL;
+
+ err = oct_get_with_idcap(&data, idcap1);
+ printf("idcap1-record: %s\n", data);
+
+ err = oct_get_with_idcap(&data, idcap2);
+ printf("idcap2-record: %s\n", data);
+}
+
+int main(int argc, char *argv[])
+{
+ oct_init();
+
+ set_records();
+ get_records();
+
+ printf("d2getset SUCESS!\n");
+ return EXIT_SUCCESS;
+}