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 
23  , m_buffers()
24 {
26 }
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);
103  msg->result = Datastore::IOError;
104  return;
105  }
106 
107  // Done
108  msg->address = range.virt;
109  msg->result = Datastore::Success;
110 
111  DEBUG("mapped `" << msg->key << "' for PID " << msg->from << " at " <<
112  (void *) msg->address << " / " << (void *) range.phys);
113 }
HashTable
Efficient key -> value lookups.
Definition: HashTable.h:44
DatastoreServer::getBufferTable
HashTable< String, Address > * getBufferTable(const ProcessID pid)
Retrieve current buffer table for given ProcessID.
Definition: DatastoreServer.cpp:28
DatastoreMessage
Datastore IPC message.
Definition: DatastoreMessage.h:36
Memory::Range
Memory range.
Definition: Memory.h:55
API::Result
Result
Enumeration of generic kernel API result codes.
Definition: API.h:68
DatastoreServer::registerBuffer
void registerBuffer(DatastoreMessage *msg)
Add a new buffer.
Definition: DatastoreServer.cpp:52
Memory::Writable
@ Writable
Definition: Memory.h:42
DatastoreServer.h
Memory::User
@ User
Definition: Memory.h:44
DatastoreServer
Datastore Server.
Definition: DatastoreServer.h:42
Assert.h
ProcessID
u32 ProcessID
Process Identification Number.
Definition: Types.h:140
DatastoreMessage::address
Address address
Address of mapped buffer inside client process.
Definition: DatastoreMessage.h:43
Address
unsigned long Address
A memory address.
Definition: Types.h:131
VMCtl
API::Result VMCtl(const ProcessID procID, const MemoryOperation op, Memory::Range *range=ZERO)
Prototype for user applications.
Definition: VMCtl.h:61
DatastoreMessage::result
Datastore::Result result
Result of action.
Definition: DatastoreMessage.h:40
Memory::Readable
@ Readable
Definition: Memory.h:41
DatastoreServer::MaximumBufferSize
static const Size MaximumBufferSize
Maximum size of a single buffer.
Definition: DatastoreServer.h:47
DEBUG
#define DEBUG(msg)
Output a debug message to standard output.
Definition: Log.h:89
DatastoreServer::DatastoreServer
DatastoreServer()
Class constructor function.
Definition: DatastoreServer.cpp:21
Release
@ Release
Definition: VMCtl.h:40
DatastoreMessage::from
ProcessID from
Source of the message.
Definition: DatastoreMessage.h:38
Memory::Range::phys
Address phys
Physical address.
Definition: Memory.h:58
Datastore::Success
@ Success
Definition: Datastore.h:44
HashTable::get
virtual const V * get(const K &key) const
Returns the first value for the given key.
Definition: HashTable.h:287
DatastoreServer::m_buffers
HashTable< ProcessID, HashTable< String, Address > * > m_buffers
Per-process hash table with key to buffers mapping.
Definition: DatastoreServer.h:77
NULL
#define NULL
NULL means zero.
Definition: Macros.h:39
Datastore::IOError
@ IOError
Definition: Datastore.h:45
Datastore::RegisterBuffer
@ RegisterBuffer
Definition: Datastore.h:36
DatastoreMessage::key
char key[32]
Key specifies the buffer to use.
Definition: DatastoreMessage.h:41
ChannelServer
Template class which serves incoming messages from Channels using MessageHandlers.
Definition: ChannelServer.h:79
Datastore::InvalidArgument
@ InvalidArgument
Definition: Datastore.h:46
ERROR
#define ERROR(msg)
Output an error message.
Definition: Log.h:61
API::Success
@ Success
Definition: API.h:70
ChannelServer< DatastoreServer, DatastoreMessage >::addIPCHandler
void addIPCHandler(const Size slot, IPCHandlerFunction h, const bool sendReply=true)
Register a new IPC message action handler.
Definition: ChannelServer.h:203
Memory::Range::virt
Address virt
Virtual address.
Definition: Memory.h:57
DatastoreMessage::size
Size size
Size of the buffer.
Definition: DatastoreMessage.h:42
Memory::Range::size
Size size
Size in number of bytes.
Definition: Memory.h:59
Memory::Range::access
Access access
Page access flags.
Definition: Memory.h:60
ZERO
#define ZERO
Zero value.
Definition: Macros.h:43
MapContiguous
@ MapContiguous
Definition: VMCtl.h:37
HashTable::insert
virtual bool insert(const K &key, const V &value)
Inserts the given item to the HashTable.
Definition: HashTable.h:133