FreeNOS
DatastoreServer.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2020 Niek Linnenbank
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <Assert.h>
19#include "DatastoreServer.h"
20
27
29{
30 HashTable<String, Address> * const *table = m_buffers.get(pid);
31
32 if (table == NULL)
33 {
35
36 if (h != ZERO)
37 m_buffers.insert(pid, h);
38
39 table = m_buffers.get(pid);
40 }
41
42 if (table != NULL)
43 {
44 return *table;
45 }
46 else
47 {
48 return ZERO;
49 }
50}
51
53{
54 // Validate the buffer size
55 if (msg->size > MaximumBufferSize)
56 {
57 ERROR("invalid buffer size: " << msg->size);
59 return;
60 }
61
62 // Retrieve buffer mapping table
64 if (!table)
65 {
66 ERROR("failed to retrieve buffer mapping table for PID " << msg->from);
68 return;
69 }
70
71 // Enforce NULL-terminated string for the key
72 msg->key[sizeof(msg->key) - 1] = 0;
73
74 // Setup buffer in the process
75 Memory::Range range;
76 range.virt = 0;
77 range.phys = 0;
78 range.size = msg->size;
80
81 // Check if the key already exists
82 const Address *addr = table->get(msg->key);
83 if (addr != ZERO)
84 {
85 range.phys = *addr;
86 }
87
88 // Create mapping in the process
89 const API::Result mapResult = VMCtl(msg->from, MapContiguous, &range);
90 if (mapResult != API::Success)
91 {
92 ERROR("failed to allocate buffer `" << msg->key << "' in PID " <<
93 msg->from << ": " << (int) mapResult);
95 return;
96 }
97
98 // Add buffer to our administration
99 if (addr == ZERO && !table->insert(msg->key, range.phys))
100 {
101 ERROR("failed to add buffer `" << msg->key << "' to mapping table for PID " << msg->from);
102 VMCtl(msg->from, Release, &range);
104 return;
105 }
106
107 // Done
108 msg->address = range.virt;
110
111 DEBUG("mapped `" << msg->key << "' for PID " << msg->from << " at " <<
112 (void *) msg->address << " / " << (void *) range.phys);
113}
Result
Enumeration of generic kernel API result codes.
Definition API.h:69
@ Success
Definition API.h:70
Template class which serves incoming messages from Channels using MessageHandlers.
void addIPCHandler(const Size slot, IPCHandlerFunction h, const bool sendReply=true)
Register a new IPC message action handler.
Datastore Server.
static const Size MaximumBufferSize
Maximum size of a single buffer.
void registerBuffer(DatastoreMessage *msg)
Add a new buffer.
DatastoreServer()
Class constructor function.
HashTable< ProcessID, HashTable< String, Address > * > m_buffers
Per-process hash table with key to buffers mapping.
HashTable< String, Address > * getBufferTable(const ProcessID pid)
Retrieve current buffer table for given ProcessID.
Efficient key -> value lookups.
Definition HashTable.h:45
virtual const V * get(const K &key) const
Returns the first value for the given key.
Definition HashTable.h:287
virtual bool insert(const K &key, const V &value)
Inserts the given item to the HashTable.
Definition HashTable.h:133
API::Result VMCtl(const ProcessID procID, const MemoryOperation op, Memory::Range *range=ZERO)
Prototype for user applications.
Definition VMCtl.h:61
@ Release
Definition VMCtl.h:40
@ MapContiguous
Definition VMCtl.h:37
#define NULL
NULL means zero.
Definition Macros.h:39
u32 ProcessID
Process Identification Number.
Definition Types.h:140
unsigned long Address
A memory address.
Definition Types.h:131
#define ERROR(msg)
Output an error message.
Definition Log.h:61
#define ZERO
Zero value.
Definition Macros.h:43
#define DEBUG(msg)
Output a debug message to standard output.
Definition Log.h:89
@ RegisterBuffer
Definition Datastore.h:36
@ InvalidArgument
Definition Datastore.h:46
@ User
Definition Memory.h:44
@ Readable
Definition Memory.h:41
@ Writable
Definition Memory.h:42
Datastore IPC message.
Address address
Address of mapped buffer inside client process.
Size size
Size of the buffer.
ProcessID from
Source of the message.
Datastore::Result result
Result of action.
char key[32]
Key specifies the buffer to use.
Memory range.
Definition Memory.h:56
Size size
Size in number of bytes.
Definition Memory.h:59
Address phys
Physical address.
Definition Memory.h:58
Address virt
Virtual address.
Definition Memory.h:57
Access access
Page access flags.
Definition Memory.h:60