Skip to content

Commit 9ed0821

Browse files
authored
Merge pull request #36 from SidoShiro/dev
Dev : Master update
2 parents ab1292f + d2bb5bc commit 9ed0821

File tree

16 files changed

+489
-213
lines changed

16 files changed

+489
-213
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ set(SRCS
2222
src/utils/debug.c
2323
src/cli/user.c
2424
src/network/communication.c
25+
src/network/data_communication.c
2526
src/utils/queue.c)
2627

2728

include/cli.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include "message.h"
1111
#include "utils.h"
1212

13-
void start_cli();
13+
void start_cli(unsigned size);
1414

1515
void send_command(enum operation op, void *data, unsigned short leader);
1616

include/communication.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,33 @@
88
// Number of attempts failed before considering the node as dead.
99
#define NB_ITER 60
1010

11+
#define TAG_MSG 3
12+
#define TAG_DATA 4
13+
#define TAG_ELECTION 5
14+
1115
/*
1216
* Send the given message 'm' to the destination node
1317
* Return 1 if it's a success, 0 if the destination node didn't respond in time
1418
*/
15-
int send_safe_message(struct message *m_send, struct queue *queue);
19+
int send_safe_message(struct message *m_send, struct queue *queue, int tag);
1620

1721
/*
1822
* Receive a message sent with 'send_safe_message'
1923
* then send a OP_OK to the source node
2024
*/
21-
struct message *receive_message(struct queue *message_queue);
25+
struct message *receive_message(struct queue *message_queue, int tag);
26+
27+
/*
28+
* Recieve a specific data from a specific node.
29+
* All others messages recieved are put in the queue. If needed, a IS_ALIVE is send.
30+
* Return the wanted data, which was calloc.
31+
*/
32+
void *recieve_data(size_t size, struct queue *queue, unsigned source);
33+
34+
/*
35+
* Send message to all nodes except user and itself
36+
* m_send->id_t will change according to the target node
37+
*/
38+
void broadcast_message(struct message *m_send, unsigned id, unsigned network_size, int tag);
2239

2340
#endif /* !DISTRIBUTEDMALLOC_COMMUNICATION_H */

include/globals.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef DISTRIBUTEDMALLOC_GLOBALS_H
22
#define DISTRIBUTEDMALLOC_GLOBALS_H
33

4-
#define DEF_NODE_SIZE 8
4+
#define DEF_NODE_SIZE 128
55
#define DEF_NODE_USER 0
66
#define DEF_NODE_LEADER 1
77

include/leader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,6 @@ void leader_loop(struct node *n, unsigned short terminal_id, unsigned short nb_n
3131

3232
struct allocation *give_for_v_address(struct leader_resources *l_r, size_t v_address, size_t *part);
3333

34+
size_t size_of_allocation(struct allocation *a);
35+
3436
#endif /* !DISTRIBUTEDMALLOC_LEADER_H */

include/message.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ enum operation {
99
OP_FREE,
1010
OP_WRITE,
1111
OP_READ,
12+
OP_READ_FILE,
13+
OP_TABLE,
1214
OP_SNAP,
1315
OP_LEADER,
16+
OP_START_LEADER,
1417
OP_WHOISLEADER,
1518
OP_REVIVE,
1619
OP_KILL,
@@ -19,6 +22,7 @@ enum operation {
1922
OP_DUMP,
2023
OP_DUMP_ALL,
2124
OP_LEADER_OK,
25+
OP_IS_ALIVE,
2226
OP_ALIVE,
2327
OP_LEADER_AGAIN
2428
};

src/cli/cli.c

Lines changed: 104 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
#include <mpi.h>
44
#include <globals.h>
55
#include <debug.h>
6+
#include <communication.h>
7+
#include <sys/stat.h>
68
#include "cli.h"
9+
#include "communication.h"
710

811
char *read_cmd() {
912
ssize_t buffer_size = 256;
@@ -84,10 +87,15 @@ void execute(char **args, unsigned short leader) {
8487
if (0 == strcmp(args[0], "h")) {
8588
printf("dmalloc commands:\n"
8689
" h | display all available commands with their description |\n"
90+
" t | show table of allocations |\n"
8791
" m `size` | return `address` to cmd user of the required allocation |\n"
8892
" f `address` | free address, Warning if already free |\n"
8993
" w `address` `datasize` `data` | write at the address the data of size datasize |\n"
94+
" w `address` `file` | write all content of file at address |\n"
95+
" w `address` `file` `datasize` | write datasize bytes from file to the address |\n"
9096
" r `address` `datasize` | read datasize bytes at address |\n"
97+
" r `address` `file` | read all bytes of the block at address into file |\n"
98+
" r `address` `file` `datasize` | read datasize bytes at address into file |\n"
9199
" d `address` | dump in as text all data of the block stored in address |\n"
92100
" d net | dump all allocation |\n"
93101
" d `address` `file` | dump address data in file |\n"
@@ -131,13 +139,17 @@ void execute(char **args, unsigned short leader) {
131139
size_t address = 0;
132140
if (1 == sscanf(args[1], "%zu", &address)) {
133141
printf("Execute Free of address : %zu\n", address);
142+
struct data_address *d_a = generate_data_address(address);
143+
send_command(OP_FREE, d_a, leader);
144+
free(d_a);
134145
} else {
135146
error_msg("f require an argument 'address' which can be casted as a positive integer");
136147
}
137148
} else if (0 == strcmp(args[0], "w")) {
138149
// ERRORS
139-
if (l <= 3) {
140-
error_msg("w require 3 arguments : 'address', 'datasize' and 'data'");
150+
if (l <= 2) {
151+
error_msg(
152+
"w require 2-3 arguments : 'address', 'datasize' and 'data'\n OR 'address' 'file' + 'datasize' optional, check h");
141153
return;
142154
} else if (l >= 5) {
143155
error_msg("w do not support more than 3 arguments, check command h");
@@ -149,23 +161,56 @@ void execute(char **args, unsigned short leader) {
149161
size_t datasize = 0;
150162
if (1 == sscanf(args[1], "%zu", &address)) {
151163
if (1 == sscanf(args[2], "%zu", &datasize)) {
164+
if (args[3] == NULL) {
165+
error_msg("w cannot write nothing");
166+
return;
167+
}
152168
printf("Execute Write at %zu of %s : %zu bytes\n", address, args[3], datasize);
153169
struct data_write *d_w = generate_data_write(address, datasize, args[3]);
154170
send_command(OP_WRITE, d_w, leader);
155171
free(d_w);
156172
} else {
157-
error_msg("w requires an argument 'datasize' which can be casted as a positive integer");
173+
// Write from File
174+
FILE *file_write = fopen(args[2], "r");
175+
if (!file_write) {
176+
error_msg("w 'address' 'file', file was not possible to open, or doesn't exist");
177+
return;
178+
}
179+
struct stat st;
180+
/*get the size using stat()*/
181+
if (stat(args[2], &st) != 0)
182+
return;
183+
if (l == 4) {
184+
// file max data read
185+
if (1 == sscanf(args[3], "%zu", &datasize)) {
186+
if ((ssize_t) datasize >= st.st_size)
187+
datasize = st.st_size;
188+
} else {
189+
error_msg("w requires an argument 'datasize' which can be casted as a positive integer");
190+
return;
191+
}
192+
} else {
193+
datasize = st.st_size;
194+
}
195+
// Now read datasize
196+
char *buffer_write_file = malloc(sizeof(char) * (2 + datasize));
197+
size_t r_c = fread(buffer_write_file, sizeof(char), datasize, file_write);
198+
if (r_c != datasize)
199+
error_msg("WARNING: file bytes read different from bytes asked");
200+
struct data_write *d_w = generate_data_write(address, datasize, buffer_write_file);
201+
send_command(OP_WRITE, d_w, leader);
202+
// OLD error_msg("w requires an argument 'datasize' which can be casted as a positive integer");
158203
}
159204
} else {
160205
error_msg("w requires an argument 'address' which can be casted as a positive integer");
161206
}
162207
} else if (0 == strcmp(args[0], "r")) {
163208
// ERRORS
164209
if (l <= 2) {
165-
error_msg("r requires 2 arguments : 'address' and 'datasize'");
210+
error_msg("r requires 2-3 arguments : 'address' and 'datasize'\n OR 'address' 'file'\n OR 'address' 'file' 'datasize");
166211
return;
167-
} else if (l >= 4) {
168-
error_msg("r do not support more than 2 arguments, check command h");
212+
} else if (l >= 5) {
213+
error_msg("r do not support more than 2-3 arguments, check command h");
169214
return;
170215
}
171216

@@ -179,7 +224,38 @@ void execute(char **args, unsigned short leader) {
179224
send_command(OP_READ, d_r, leader);
180225
free(d_r);
181226
} else {
182-
error_msg("r requires an argument 'datasize' which can be casted as a positive integer");
227+
// Read to File
228+
FILE *file_read = fopen(args[2], "w");
229+
if (!file_read) {
230+
error_msg("r 'address' 'file', file was not possible to open, or doesn't exist");
231+
return;
232+
}
233+
struct stat st;
234+
if (stat(args[2], &st) != 0)
235+
return;
236+
if (l == 4) {
237+
// file max data read
238+
if (1 == sscanf(args[3], "%zu", &datasize)) {
239+
if ((ssize_t) datasize >= st.st_size)
240+
datasize = st.st_size;
241+
} else {
242+
error_msg("r requires an argument 'datasize' which can be casted as a positive integer");
243+
return;
244+
}
245+
} else {
246+
datasize = st.st_size;
247+
}
248+
// Now read datasize bytes
249+
char *buffer_read_file = NULL;
250+
struct data_write *d_w = generate_data_write(address, datasize, buffer_read_file);
251+
send_command(OP_READ_FILE, d_w, leader);
252+
// /!\ buffer_read_file was allocated in send_command
253+
debug("Write data in file (READ OP)", 0);
254+
printf("Data Read :: %zu", d_w->size);
255+
size_t r_c = fwrite(d_w->data, sizeof(char), d_w->size, file_read);
256+
if (r_c != d_w->size)
257+
error_msg("WARNING: file bytes write different from bytes asked");
258+
// OLD error_msg("r requires an argument 'datasize' which can be casted as a positive integer");
183259
}
184260
} else {
185261
error_msg("r require an argument 'address' which can be casted as a positive integer");
@@ -239,28 +315,14 @@ void execute(char **args, unsigned short leader) {
239315
} else {
240316
error_msg("w require an argument 'address' which can be casted as a positive integer");
241317
}
242-
} else if (0 == strcmp(args[0], "w")) {
318+
} else if (0 == strcmp(args[0], "t")) {
243319
// ERRORS
244-
if (l <= 3) {
245-
error_msg("w require 3 arguments : 'address', 'datasize' and 'data'");
246-
return;
247-
} else if (l >= 5) {
248-
error_msg("w do not support more than 3 arguments, check command h");
320+
if (l != 1) {
321+
error_msg("t require no arguments");
249322
return;
250323
}
324+
send_command(OP_TABLE, NULL, leader);
251325

252-
// Execution
253-
size_t address = 0;
254-
size_t datasize = 0;
255-
if (1 == sscanf(args[1], "%zu", &address)) {
256-
if (1 == sscanf(args[2], "%zu", &datasize)) {
257-
printf("Execute Write at %zu of %s : %zu bytes\n", address, args[3], datasize);
258-
} else {
259-
error_msg("w require an argument 'datasize' which can be casted as a positive integer");
260-
}
261-
} else {
262-
error_msg("w require an argument 'address' which can be casted as a positive integer");
263-
}
264326
} else if (0 == strcmp(args[0], "w")) {
265327
// ERRORS
266328
if (l <= 3) {
@@ -283,23 +345,31 @@ void execute(char **args, unsigned short leader) {
283345
} else {
284346
error_msg("w require an argument 'address' which can be casted as a positive integer");
285347
}
348+
} else {
349+
error_msg("command not found, see 'h' for help");
286350
}
287351

288352
}
289353

290-
unsigned short get_leader() {
354+
unsigned short start_leader_election(unsigned size) {
355+
struct message *b = generate_message(0, 0, 0, 0, 0, OP_START_LEADER);
356+
broadcast_message(b, 0, size, TAG_MSG);
357+
free(b);
291358
struct message *m = generate_message(0, 0, 0, 0, 0, OP_NONE);
292-
MPI_Recv(m, sizeof(*m), MPI_BYTE, MPI_ANY_SOURCE, 201, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
359+
MPI_Recv(m, sizeof(*m), MPI_BYTE, MPI_ANY_SOURCE, TAG_MSG, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
293360
debug("Got Leader !", DEF_NODE_USER);
294-
return m->id_o;
361+
unsigned short leader = m->id_o;
362+
free(m);
363+
return leader;
295364
}
296365

297-
void start_cli() {
366+
void start_cli(unsigned size) {
298367
int no_quit = 1;
299368
char *cmd;
300369
char **args;
301370

302-
unsigned short leader = get_leader();
371+
struct queue *q = queue_init();
372+
unsigned short leader = start_leader_election(size);
303373

304374
while (no_quit) {
305375
fflush(0);
@@ -315,7 +385,10 @@ void start_cli() {
315385
}
316386

317387
// DEBUG print_args(args);
318-
388+
struct message *m_verif = generate_message_a(0, leader, 0, 0, 0, OP_IS_ALIVE, 1);
389+
if (!send_safe_message(m_verif, q, TAG_MSG))
390+
leader = start_leader_election(size);
391+
free(m_verif);
319392
execute(args, leader);
320393

321394
free(cmd);

0 commit comments

Comments
 (0)