static void KineticMessage_HeaderInit(Com__Seagate__Kinetic__Proto__Command__Header* hdr, KineticSession const * const session) { KINETIC_ASSERT(hdr != NULL); KINETIC_ASSERT(session != NULL); *hdr = (Com__Seagate__Kinetic__Proto__Command__Header) { .base = PROTOBUF_C_MESSAGE_INIT(&com__seagate__kinetic__proto__command__header__descriptor), .has_clusterversion = true, .clusterversion = session->config.clusterVersion, .has_connectionid = true, .connectionid = session->connectionID, .has_sequence = true, .sequence = KINETIC_SEQUENCE_NOT_YET_BOUND, }; } void KineticRequest_Init(KineticRequest* request, KineticSession const * const session) { KINETIC_ASSERT(request != NULL); KINETIC_ASSERT(session != NULL); memset(request, 0, sizeof(KineticRequest)); KineticMessage_Init(&(request->message)); KineticMessage_HeaderInit(&(request->message.header), session); request->command = &request->message.command; request->command->header = &request->message.header; }
KineticStatus KineticClient_Put(KineticSession* const session, KineticEntry* const entry, KineticCompletionClosure* closure) { KINETIC_ASSERT(session); KINETIC_ASSERT(entry); // Assert non-NULL value upon non-zero length if (entry->value.array.len > 0) { KINETIC_ASSERT(entry->value.array.data); } KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) {return KINETIC_STATUS_MEMORY_ERROR;} KINETIC_ASSERT(operation->session == session); // Initialize request KineticStatus status = KineticBuilder_BuildPut(operation, entry); if (status != KINETIC_STATUS_SUCCESS) { KineticAllocator_FreeOperation(operation); return status; } // Execute the operation KineticStatus res = KineticController_ExecuteOperation(operation, closure); return res; }
KineticStatus KineticController_ExecuteOperation(KineticOperation* operation, KineticCompletionClosure* const closure) { KINETIC_ASSERT(operation != NULL); KINETIC_ASSERT(operation->session != NULL); KineticStatus status = KINETIC_STATUS_INVALID; KineticSession *session = operation->session; if (KineticSession_GetTerminationStatus(operation->session) != KINETIC_STATUS_SUCCESS) { return KINETIC_STATUS_SESSION_TERMINATED; } if (closure != NULL) { operation->closure = *closure; return KineticOperation_SendRequest(operation); } else { DefaultCallbackData data; pthread_mutex_init(&data.receiveCompleteMutex, NULL); pthread_cond_init(&data.receiveComplete, NULL); data.status = KINETIC_STATUS_INVALID; data.completed = false; operation->closure = DefaultClosure(&data); // Send the request status = KineticOperation_SendRequest(operation); if (status == KINETIC_STATUS_SUCCESS) { pthread_mutex_lock(&data.receiveCompleteMutex); while(data.completed == false) { pthread_cond_wait(&data.receiveComplete, &data.receiveCompleteMutex); } status = data.status; pthread_mutex_unlock(&data.receiveCompleteMutex); } pthread_cond_destroy(&data.receiveComplete); pthread_mutex_destroy(&data.receiveCompleteMutex); if (status != KINETIC_STATUS_SUCCESS) { if (KineticSession_GetTerminationStatus(session) != KINETIC_STATUS_SUCCESS) { (void)KineticSession_Disconnect(session); if (status == KINETIC_STATUS_SOCKET_ERROR) { status = KINETIC_STATUS_SESSION_TERMINATED; } } } return status; } }
void KineticLogger_Init(const char* log_file, int log_level) { KineticLogLevel = -1; pthread_mutex_init(&BufferMutex, NULL); KineticLoggerHandle = NULL; if (log_file == NULL) { printf("\nLogging kinetic-c output is disabled!\n"); return; } else { KineticLogLevel = log_level; if (strncmp(log_file, "stdout", 4) == 0 || strncmp(log_file, "STDOUT", 4) == 0) { if (log_level > 0) { printf("Logging kinetic-c output to console (stdout) w/ log_level=%d\n", KineticLogLevel); } KineticLoggerHandle = stdout; } else { if (log_level > 0) { printf("Logging kinetic-c output to %s w/ log_level=%d\n", log_file, KineticLogLevel); } KineticLoggerHandle = fopen(log_file, "a+"); KINETIC_ASSERT(KineticLoggerHandle != NULL); } log_version_info(); } }
KineticStatus KineticClient_Delete(KineticSession* const session, KineticEntry* const entry, KineticCompletionClosure* closure) { KINETIC_ASSERT(session); KINETIC_ASSERT(entry); KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) {return KINETIC_STATUS_MEMORY_ERROR;} // Initialize request KineticBuilder_BuildDelete(operation, entry); // Execute the operation return KineticController_ExecuteOperation(operation, closure); }
KineticStatus KineticAdminClient_SetACL(KineticSession * const session, const char *ACLPath) { KINETIC_ASSERT(session != NULL); if (ACLPath == NULL) { return KINETIC_STATUS_INVALID_REQUEST; } #ifndef TEST struct ACL *ACLs = NULL; #endif KineticACLLoadResult acl_res = KineticACL_LoadFromFile(ACLPath, &ACLs); if (acl_res != ACL_OK) { return KINETIC_STATUS_ACL_ERROR; } KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) { printf("!operation\n"); return KINETIC_STATUS_MEMORY_ERROR; } // Initialize request KineticBuilder_BuildSetACL(operation, ACLs); KineticStatus status = KineticController_ExecuteOperation(operation, NULL); return status; }
void KineticCountingSemaphore_Destroy(KineticCountingSemaphore * const sem) { KINETIC_ASSERT(sem != NULL); pthread_mutex_destroy(&sem->mutex); pthread_cond_destroy(&sem->available); free(sem); }
void KineticEntry_Init(KineticEntry* entry) { KINETIC_ASSERT(entry != NULL); *entry = (KineticEntry) { .key = BYTE_BUFFER_NONE, .value = BYTE_BUFFER_NONE }; }
KineticStatus KineticAdminClient_GetDeviceSpecificLog(KineticSession * const session, ByteArray name, KineticLogInfo** info, KineticCompletionClosure* closure) { KINETIC_ASSERT(session != NULL); KINETIC_ASSERT(info != NULL); KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) {return KINETIC_STATUS_MEMORY_ERROR;} // Initialize request KineticBuilder_BuildGetLog(operation, COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__DEVICE, name, info); // Execute the operation return KineticController_ExecuteOperation(operation, closure); }
KineticStatus KineticBuilder_BuildGetKeyRange(KineticOperation* const op, KineticKeyRange* range, ByteBufferArray* buffers) { KineticOperation_ValidateOperation(op); KINETIC_ASSERT(range != NULL); KINETIC_ASSERT(buffers != NULL); op->request->command->header->messagetype = COM__SEAGATE__KINETIC__PROTO__COMMAND__MESSAGE_TYPE__GETKEYRANGE; op->request->command->header->has_messagetype = true; KineticMessage_ConfigureKeyRange(&op->request->message, range); op->buffers = buffers; op->opCallback = &KineticCallbacks_GetKeyRange; return KINETIC_STATUS_SUCCESS; }
void KineticCountingSemaphore_Give(KineticCountingSemaphore * const sem) // SIGNAL { KINETIC_ASSERT(sem != NULL); pthread_mutex_lock(&sem->mutex); if (sem->count == 0 && sem->num_waiting > 0) { pthread_cond_signal(&sem->available); } uint32_t before = sem->count++; uint32_t after = sem->count; uint32_t waiting = sem->num_waiting; pthread_mutex_unlock(&sem->mutex); LOGF3("Concurrent ops throttle -- GIVE: %u => %u (waiting=%u)", before, after, waiting); KINETIC_ASSERT(sem->max >= after); }
void KineticAdminClient_FreeLogInfo(KineticSession * const session, KineticLogInfo* info) { KINETIC_ASSERT(session != NULL); if (info) { KineticLogInfo_Free(info); } /* The session is not currently used, but part of the API to allow * a different memory management strategy. */ (void)session; }
KineticStatus KineticClient_NoOp(KineticSession* const session) { KINETIC_ASSERT(session); KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) {return KINETIC_STATUS_MEMORY_ERROR;} KineticBuilder_BuildNoop(operation); return KineticController_ExecuteOperation(operation, NULL); }
void KineticController_HandleResult(bus_msg_result_t *res, void *udata) { KineticOperation* op = udata; KINETIC_ASSERT(op); KINETIC_ASSERT(op->session); KineticStatus status = bus_to_kinetic_status(res->status); if (status == KINETIC_STATUS_SUCCESS) { KineticResponse * response = res->u.response.opaque_msg; status = KineticResponse_GetStatus(response); LOGF2("[PDU RX] pdu: %p, session: %p, bus: %p, " "fd: %6d, seq: %8lld, protoLen: %8u, valueLen: %8u, op: %p, status: %s", (void*)response, (void*)op->session, (void*)op->session->messageBus, op->session->socket, response->command->header->acksequence, KineticResponse_GetProtobufLength(response), KineticResponse_GetValueLength(response), (void*)op, Kinetic_GetStatusDescription(status)); KineticLogger_LogHeader(3, &response->header); KineticLogger_LogProtobuf(3, response->proto); if (op->response == NULL) { op->response = response; } } else { LOGF0("Error receiving response, got message bus error: %s", bus_error_string(res->status)); if (res->status == BUS_SEND_RX_TIMEOUT) { LOG0("RX_TIMEOUT"); } } // Call operation-specific callback, if configured if (op->opCallback != NULL) { status = op->opCallback(op, status); } KineticOperation_Complete(op, status); }
KineticStatus KineticAdminClient_SetClusterVersion(KineticSession * const session, int64_t version) { KINETIC_ASSERT(session != NULL); KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) {return KINETIC_STATUS_MEMORY_ERROR;} KineticBuilder_BuildSetClusterVersion(operation, version); return KineticController_ExecuteOperation(operation, NULL); }
KineticStatus KineticClient_GetKeyRange(KineticSession* const session, KineticKeyRange* range, ByteBufferArray* keys, KineticCompletionClosure* closure) { KINETIC_ASSERT(session); KINETIC_ASSERT(range); KINETIC_ASSERT(keys); KINETIC_ASSERT(keys->buffers); KINETIC_ASSERT(keys->count > 0); KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) {return KINETIC_STATUS_MEMORY_ERROR;} // Initialize request KineticBuilder_BuildGetKeyRange(operation, range, keys); // Execute the operation return KineticController_ExecuteOperation(operation, closure); }
void KineticMessage_ConfigureKeyRange(KineticMessage* const message, const KineticKeyRange* range) { KINETIC_ASSERT(message != NULL); KINETIC_ASSERT(range != NULL); KINETIC_ASSERT(range->startKey.array.data != NULL); KINETIC_ASSERT(range->startKey.array.len > 0); KINETIC_ASSERT(range->startKey.bytesUsed > 0); KINETIC_ASSERT(range->startKey.bytesUsed <= range->startKey.array.len); KINETIC_ASSERT(range->maxReturned > 0); // Enable command body and keyValue fields by pointing at // pre-allocated elements in message message->command.body = &message->body; message->command.body->range = &message->keyRange; // Populate startKey, if supplied message->command.body->range->has_startkey = (range->startKey.array.data != NULL); if (message->command.body->range->has_startkey) { message->command.body->range->startkey = (ProtobufCBinaryData) { .data = range->startKey.array.data, .len = range->startKey.bytesUsed, }; } // Populate endKey, if supplied message->command.body->range->has_endkey = (range->endKey.array.data != NULL); if (message->command.body->range->has_endkey) { message->command.body->range->endkey = (ProtobufCBinaryData) { .data = range->endKey.array.data, .len = range->endKey.bytesUsed, }; } // Populate start/end key inclusive flags, if specified if (range->startKeyInclusive) { message->command.body->range->startkeyinclusive = range->startKeyInclusive; } message->command.body->range->has_startkeyinclusive = range->startKeyInclusive; if (range->endKeyInclusive) { message->command.body->range->endkeyinclusive = range->endKeyInclusive; } message->command.body->range->has_endkeyinclusive = range->endKeyInclusive; // Populate max keys to return message->command.body->range->maxreturned = range->maxReturned; message->command.body->range->has_maxreturned = true; // Populate reverse flag (return keys in reverse order) if (range->reverse) { message->command.body->range->reverse = range->reverse; } message->command.body->range->has_reverse = range->reverse; }
void KineticMessage_ConfigureKeyValue(KineticMessage* const message, const KineticEntry* entry) { KINETIC_ASSERT(message != NULL); KINETIC_ASSERT(entry != NULL); // Enable command body and keyValue fields by pointing at // pre-allocated elements in message message->command.body = &message->body; message->command.body->keyvalue = &message->keyValue; // Set keyValue fields appropriately CONFIG_FIELD_BYTE_BUFFER(key, key, message->keyValue, entry); CONFIG_FIELD_BYTE_BUFFER(newVersion, newversion, message->keyValue, entry); CONFIG_FIELD_BYTE_BUFFER(dbVersion, dbversion, message->keyValue, entry); CONFIG_FIELD_BYTE_BUFFER(tag, tag, message->keyValue, entry); message->keyValue.has_force = (bool)((int)entry->force); if (message->keyValue.has_force) { message->keyValue.force = entry->force; } message->keyValue.has_algorithm = (bool)((int)entry->algorithm > 0); if (message->keyValue.has_algorithm) { message->keyValue.algorithm = Com__Seagate__Kinetic__Proto__Command__Algorithm_from_KineticAlgorithm(entry->algorithm); } message->keyValue.has_metadataonly = entry->metadataOnly; if (message->keyValue.has_metadataonly) { message->keyValue.metadataonly = entry->metadataOnly; } message->keyValue.has_synchronization = (entry->synchronization > 0); if (message->keyValue.has_synchronization) { message->keyValue.synchronization = Com__Seagate__Kinetic__Proto__Command__Synchronization_from_KineticSynchronization( entry->synchronization); } }
KineticStatus KineticSession_Connect(KineticSession * const session) { if (session == NULL) { return KINETIC_STATUS_SESSION_EMPTY; } // Establish the connection KINETIC_ASSERT(strlen(session->config.host) > 0); session->socket = KineticSocket_Connect( session->config.host, session->config.port); if (session->socket == KINETIC_SOCKET_DESCRIPTOR_INVALID) { LOG0("Session connection failed!"); session->socket = KINETIC_SOCKET_DESCRIPTOR_INVALID; session->connected = false; return KINETIC_STATUS_CONNECTION_ERROR; } session->connected = true; bus_socket_t socket_type = session->config.useSsl ? BUS_SOCKET_SSL : BUS_SOCKET_PLAIN; session->si = calloc(1, sizeof(socket_info) + 2 * PDU_PROTO_MAX_LEN); if (session->si == NULL) { return KINETIC_STATUS_MEMORY_ERROR; } bool success = Bus_RegisterSocket(session->messageBus, socket_type, session->socket, session); if (!success) { LOG0("Failed registering connection with client!"); goto connection_error_cleanup; } // Wait for initial unsolicited status to be received in order to obtain connection ID success = KineticResourceWaiter_WaitTilAvailable(&session->connectionReady, KINETIC_CONNECTION_TIMEOUT_SECS); if (!success) { LOG0("Timed out waiting for connection ID from device!"); goto connection_error_cleanup; } LOGF1("Received connection ID %lld for session %p", (long long)KineticSession_GetConnectionID(session), (void*)session); return KINETIC_STATUS_SUCCESS; connection_error_cleanup: if (session->si != NULL) { free(session->si); session->si = NULL; } if (session->socket != KINETIC_SOCKET_DESCRIPTOR_INVALID) { KineticSocket_Close(session->socket); session->socket = KINETIC_SOCKET_DESCRIPTOR_INVALID; } session->connected = false; return KINETIC_STATUS_CONNECTION_ERROR; }
KineticStatus KineticClient_P2POperation(KineticSession* const session, KineticP2P_Operation* const p2pOp, KineticCompletionClosure* closure) { KINETIC_ASSERT(session); KINETIC_ASSERT(p2pOp); KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) {return KINETIC_STATUS_MEMORY_ERROR;} // Initialize request KineticStatus status = KineticBuilder_BuildP2POperation(operation, p2pOp); if (status != KINETIC_STATUS_SUCCESS) { // TODO we need to find a more generic way to handle errors on command construction if (closure != NULL) { operation->closure = *closure; } return status; } // Execute the operation return KineticController_ExecuteOperation(operation, closure); }
KineticStatus KineticAdminClient_GetLog(KineticSession * const session, KineticLogInfo_Type type, KineticLogInfo** info, KineticCompletionClosure* closure) { KINETIC_ASSERT(session != NULL); KINETIC_ASSERT(info != NULL); Com__Seagate__Kinetic__Proto__Command__GetLog__Type protoType = KineticLogInfo_Type_to_Com__Seagate__Kinetic__Proto__Command__GetLog__Type(type); if (protoType == COM__SEAGATE__KINETIC__PROTO__COMMAND__GET_LOG__TYPE__INVALID_TYPE) { return KINETIC_STATUS_INVALID_LOG_TYPE; } KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) {return KINETIC_STATUS_MEMORY_ERROR;} // Initialize request KineticBuilder_BuildGetLog(operation, protoType, BYTE_ARRAY_NONE, info); // Execute the operation return KineticController_ExecuteOperation(operation, closure); }
static KineticStatus handle_get_command(GET_COMMAND cmd, KineticSession* const session, KineticEntry* const entry, KineticCompletionClosure* closure) { KINETIC_ASSERT(session); KINETIC_ASSERT(entry); if (!has_key(entry)) {return KINETIC_STATUS_MISSING_KEY;} if (!has_value_buffer(entry) && !entry->metadataOnly) { return KINETIC_STATUS_MISSING_VALUE_BUFFER; } KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) { return KINETIC_STATUS_MEMORY_ERROR; } // Initialize request switch (cmd) { case CMD_GET: KineticBuilder_BuildGet(operation, entry); break; case CMD_GET_NEXT: KineticBuilder_BuildGetNext(operation, entry); break; case CMD_GET_PREVIOUS: KineticBuilder_BuildGetPrevious(operation, entry); break; default: KINETIC_ASSERT(false); } // Execute the operation return KineticController_ExecuteOperation(operation, closure); }
KineticStatus KineticAdminClient_MediaOptimize(KineticSession * const session, const KineticMediaOptimize_Operation* mediaoptimize_operation, KineticCommand_Priority priority) { KINETIC_ASSERT(session != NULL); KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) {return KINETIC_STATUS_MEMORY_ERROR;} KineticStatus status = KineticBuilder_BuildMediaOptimize(operation, mediaoptimize_operation, priority); if (status != KINETIC_STATUS_SUCCESS) { return status; } return KineticController_ExecuteOperation(operation, NULL); }
KineticStatus KineticAdminClient_UpdateFirmware(KineticSession * const session, char const * const fw_path) { KINETIC_ASSERT(session != NULL); KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) {return KINETIC_STATUS_MEMORY_ERROR;} KineticStatus status = KineticBuilder_BuildUpdateFirmware(operation, fw_path); if (status != KINETIC_STATUS_SUCCESS) { return status; } return KineticController_ExecuteOperation(operation, NULL); }
KineticStatus bus_to_kinetic_status(bus_send_status_t const status) { KineticStatus res = KINETIC_STATUS_INVALID; switch(status) { // TODO scrutinize all these mappings case BUS_SEND_SUCCESS: res = KINETIC_STATUS_SUCCESS; break; case BUS_SEND_TX_TIMEOUT_NOTIFYING_LISTENER: case BUS_SEND_TX_TIMEOUT: res = KINETIC_STATUS_SOCKET_TIMEOUT; break; case BUS_SEND_TX_FAILURE: res = KINETIC_STATUS_SOCKET_ERROR; break; case BUS_SEND_RX_TIMEOUT: res = KINETIC_STATUS_OPERATION_TIMEDOUT; break; case BUS_SEND_RX_FAILURE: res = KINETIC_STATUS_SOCKET_ERROR; break; case BUS_SEND_BAD_RESPONSE: res = KINETIC_STATUS_SOCKET_ERROR; break; case BUS_SEND_UNREGISTERED_SOCKET: res = KINETIC_STATUS_SOCKET_ERROR; break; case BUS_SEND_RX_TIMEOUT_EXPECT: res = KINETIC_STATUS_OPERATION_TIMEDOUT; break; case BUS_SEND_UNDEFINED: default: { LOGF0("bus_to_kinetic_status: UNMATCHED %d", status); KINETIC_ASSERT(false); return KINETIC_STATUS_INVALID; } } LOGF3("bus_to_kinetic_status: mapping status %d => %d", status, res); return res; }
void KineticMessage_Init(KineticMessage* const message) { KINETIC_ASSERT(message != NULL); com__seagate__kinetic__proto__message__init(&message->message); com__seagate__kinetic__proto__command__init(&message->command); com__seagate__kinetic__proto__message__hmacauth__init(&message->hmacAuth); com__seagate__kinetic__proto__message__pinauth__init(&message->pinAuth); com__seagate__kinetic__proto__command__header__init(&message->header); com__seagate__kinetic__proto__command__status__init(&message->status); com__seagate__kinetic__proto__command__body__init(&message->body); com__seagate__kinetic__proto__command__key_value__init(&message->keyValue); com__seagate__kinetic__proto__command__range__init(&message->keyRange); com__seagate__kinetic__proto__command__setup__init(&message->setup); com__seagate__kinetic__proto__command__get_log__init(&message->getLog); com__seagate__kinetic__proto__command__get_log__device__init(&message->getLogDevice); com__seagate__kinetic__proto__command__security__init(&message->security); com__seagate__kinetic__proto__command__pin_operation__init(&message->pinOp); }
KineticStatus KineticAdminClient_InstantErase(KineticSession * const session, ByteArray pin) { KINETIC_ASSERT(session != NULL); KineticStatus status; status = KineticAuth_EnsureSslEnabled(&session->config); if (status != KINETIC_STATUS_SUCCESS) {return status;} // Ensure PIN array has data if non-empty if (pin.len > 0 && pin.data == NULL) { return KINETIC_STATUS_MISSING_PIN; } KineticOperation* operation = KineticAllocator_NewOperation(session); if (operation == NULL) {return KINETIC_STATUS_MEMORY_ERROR;} KineticBuilder_BuildErase(operation, false, &pin); return KineticController_ExecuteOperation(operation, NULL); }
void KineticCountingSemaphore_Take(KineticCountingSemaphore * const sem) // WAIT { KINETIC_ASSERT(sem != NULL); pthread_mutex_lock(&sem->mutex); sem->num_waiting++; while (sem->count == 0) { pthread_cond_wait(&sem->available, &sem->mutex); } sem->num_waiting--; uint32_t before = sem->count--; uint32_t after = sem->count; uint32_t waiting = sem->num_waiting; pthread_mutex_unlock(&sem->mutex); LOGF3("Concurrent ops throttle -- TAKE: %u => %u (waiting=%u)", before, after, waiting); }
Com__Seagate__Kinetic__Proto__Command__P2POperation* build_p2pOp(uint32_t nestingLevel, KineticP2P_Operation const * const p2pOp) { // limit nesting level to KINETIC_P2P_MAX_NESTING if (nestingLevel >= KINETIC_P2P_MAX_NESTING) { LOGF0("P2P op nesting level is too deep. Max is %d.", KINETIC_P2P_MAX_NESTING); return NULL; } Com__Seagate__Kinetic__Proto__Command__P2POperation* proto_p2pOp = calloc(1, sizeof(Com__Seagate__Kinetic__Proto__Command__P2POperation)); if (proto_p2pOp == NULL) { goto error_cleanup; } com__seagate__kinetic__proto__command__p2_poperation__init(proto_p2pOp); proto_p2pOp->peer = calloc(1, sizeof(Com__Seagate__Kinetic__Proto__Command__P2POperation__Peer)); if (proto_p2pOp->peer == NULL) { goto error_cleanup; } com__seagate__kinetic__proto__command__p2_poperation__peer__init(proto_p2pOp->peer); proto_p2pOp->peer->hostname = p2pOp->peer.hostname; proto_p2pOp->peer->has_port = true; proto_p2pOp->peer->port = p2pOp->peer.port; proto_p2pOp->peer->has_tls = true; proto_p2pOp->peer->tls = p2pOp->peer.tls; proto_p2pOp->n_operation = p2pOp->numOperations; proto_p2pOp->operation = calloc(p2pOp->numOperations, sizeof(Com__Seagate__Kinetic__Proto__Command__P2POperation__Operation*)); if (proto_p2pOp->operation == NULL) { goto error_cleanup; } for(size_t i = 0; i < proto_p2pOp->n_operation; i++) { KINETIC_ASSERT(!ByteBuffer_IsNull(p2pOp->operations[i].key)); // TODO return invalid operand? Com__Seagate__Kinetic__Proto__Command__P2POperation__Operation * p2p_op_op = calloc(1, sizeof(Com__Seagate__Kinetic__Proto__Command__P2POperation__Operation)); if (p2p_op_op == NULL) { goto error_cleanup; } com__seagate__kinetic__proto__command__p2_poperation__operation__init(p2p_op_op); p2p_op_op->has_key = true; p2p_op_op->key.data = p2pOp->operations[i].key.array.data; p2p_op_op->key.len = p2pOp->operations[i].key.bytesUsed; p2p_op_op->has_newkey = !ByteBuffer_IsNull(p2pOp->operations[i].newKey); p2p_op_op->newkey.data = p2pOp->operations[i].newKey.array.data; p2p_op_op->newkey.len = p2pOp->operations[i].newKey.bytesUsed; p2p_op_op->has_version = !ByteBuffer_IsNull(p2pOp->operations[i].version); p2p_op_op->version.data = p2pOp->operations[i].version.array.data; p2p_op_op->version.len = p2pOp->operations[i].version.bytesUsed; // force if no version was specified p2p_op_op->has_force = ByteBuffer_IsNull(p2pOp->operations[i].version); p2p_op_op->force = ByteBuffer_IsNull(p2pOp->operations[i].version); if (p2pOp->operations[i].chainedOperation == NULL) { p2p_op_op->p2pop = NULL; } else { p2p_op_op->p2pop = build_p2pOp(nestingLevel + 1, p2pOp->operations[i].chainedOperation); if (p2p_op_op->p2pop == NULL) { goto error_cleanup; } } p2p_op_op->status = NULL; proto_p2pOp->operation[i] = p2p_op_op; } return proto_p2pOp; error_cleanup: KineticAllocator_FreeP2PProtobuf(proto_p2pOp); return NULL; }
void KineticEntry_SetAlgorithm(KineticEntry* entry, KineticAlgorithm algorithm) { KINETIC_ASSERT(entry != NULL); entry->algorithm = algorithm; }