Distributed File System written in C
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat!: Finish copy to server implementation

+94 -39
+30 -5
src/copy.c
··· 76 76 conecta(enchufe); 77 77 78 78 if (from_server) { 79 + Command get = (Command){ 80 + .tag = GET, 81 + .as.get.fname = atoss(source), 82 + }; 83 + Buffer get_buf = Command_serialize(get); 84 + printf("INFO: Sending GET Command to metadata server.\n"); 85 + zumba(enchufe, get_buf); 86 + free(get_buf.buf); 87 + Byte buf[BUF_LEN] = {0}; 88 + Buffer outside_buf = (Buffer){ 89 + .buf = buf, 90 + .len = BUF_LEN, 91 + }; 92 + size_t len = recibe(enchufe, outside_buf); 93 + outside_buf.len = len; 94 + ListDNodeInfo dinfo = ListDNodeInfo_deserialize(outside_buf); 95 + 96 + 79 97 } else { 80 98 LazyBuffer b = open(source); 81 99 exists(b.fptr); ··· 118 136 size_t chunks_per_dnode = 1 + (chunk_count - 1) / dnode_count; 119 137 120 138 ListDNodeInfo dinfo = NULL; 139 + size_t seq = 1; 121 140 for (ListDNode dptr = dnodes; dptr != NULL; dptr = dptr ->rest) { 122 141 DNode d = dptr->head; 123 142 printf("INFO: Creating socket for DNode\n"); ··· 143 162 len = recibe(d_enc, cid_buf); 144 163 UUID cid = UUID_deserialize(cid_buf); 145 164 146 - while (true) { 165 + for (size_t sent_chunks = 0; sent_chunks < chunks_per_dnode; sent_chunks++) { 147 166 b = next_chunk(b); 148 167 if (b.len == 0) break; 149 168 150 169 printf("INFO: Sending %zu bytes to data node.\n", b.size); 151 170 zumba(d_enc, (Buffer){ .buf = b.buf, .len = b.len }); 152 - dinfo = ListDNodeInfo_cons((DNodeInfo){ 171 + } 172 + printf("INFO: Sequence number is: %zu\n", seq); 173 + dinfo = ListDNodeInfo_cons((DNodeInfo){ 174 + .dnode = { 153 175 .address = d.address, 154 - .cid = cid, 155 176 .port = d.port, 156 - }, dinfo); 157 - } 177 + .nid = (UUID){0}, 178 + }, 179 + .cid = cid, 180 + .seq = seq, 181 + }, dinfo); 182 + seq += 1; 158 183 printf("INFO: Disconnecting from data node.\n"); 159 184 desenchufa(d_enc); 160 185 }
+22 -11
src/lib/block.c
··· 8 8 Buffer fid_buf = UUID_serialize(block.fid); 9 9 Buffer nid_buf = UUID_serialize(block.nid); 10 10 Buffer cid_buf = UUID_serialize(block.cid); 11 + Buffer seq_buf = size_t_serialize(block.seq); 11 12 12 - return concat(bid_buf, concat(fid_buf, concat(nid_buf, cid_buf))); 13 + return concat(bid_buf, 14 + concat(fid_buf, 15 + concat(nid_buf, 16 + concat(cid_buf, seq_buf)))); 13 17 } 14 18 15 19 Block Block_deserialize(Buffer buf) { ··· 37 41 }; 38 42 UUID cid = UUID_deserialize(cid_buf); 39 43 44 + Buffer seq_buf = { 45 + .len = sizeof(size_t), 46 + .buf = buf.buf + sizeof(UUID) * 4, 47 + }; 48 + size_t seq = size_t_deserialize(seq_buf); 49 + 40 50 return (Block){ 41 51 .bid = bid, 42 52 .fid = fid, 43 53 .nid = nid, 44 54 .cid = cid, 55 + .seq = seq, 45 56 }; 46 57 } 47 58 ··· 64 75 return ListBlock_reverse(out); 65 76 } 66 77 67 - void insert_into_block(UUID* fid, UUID* nid, UUID* cid) { 78 + void insert_into_block(UUID* fid, UUID* nid, UUID* cid, size_t* seq) { 68 79 Block block = { 69 80 .bid = new_uuid(), 70 81 .fid = fid != NULL ? *fid : (UUID){0}, 71 82 .nid = nid != NULL ? *nid : (UUID){0}, 72 83 .cid = cid != NULL ? *cid : (UUID){0}, 84 + .seq = seq != NULL ? *seq : 0, 73 85 }; 74 86 75 87 ListBlock blocks = Block_get_db(); 76 - ListBlock old_blocks = blocks; 88 + 77 89 bool unique = true; 78 - while (blocks != NULL) { 79 - Block current = blocks->head; 80 - blocks = blocks->rest; 81 - if (UUID_eq(current.nid, block.nid) && UUID_eq(current.cid, block.cid)) 90 + for (ListBlock bptr = blocks; bptr != NULL; bptr = bptr->rest) { 91 + Block b = bptr->head; 92 + if (UUID_eq(b.nid, block.nid) && UUID_eq(b.cid, block.cid)) 82 93 unique = false; 83 94 } 84 - blocks = old_blocks; 85 95 86 96 if (unique) { 87 97 printf("LOGBLOCK: Inserted tuple: "); ··· 98 108 ListBlock_deinit(blocks); 99 109 } 100 110 101 - ListBlock select_from_block(UUID* bid, UUID* fid, UUID* nid, UUID* cid) { 111 + ListBlock select_from_block(UUID* bid, UUID* fid, UUID* nid, UUID* cid, size_t* seq) { 102 112 ListBlock out = NULL; 103 113 ListBlock blocks = Block_get_db(); 104 114 for (ListBlock bptr = blocks; bptr != NULL; bptr = bptr->rest) { ··· 106 116 if ((bid != NULL ? UUID_eq(*bid, b.bid) : true) 107 117 && (fid != NULL ? UUID_eq(*fid, b.fid) : true) 108 118 && (nid != NULL ? UUID_eq(*nid, b.nid) : true) 109 - && (cid != NULL ? UUID_eq(*cid, b.cid) : true)) { 119 + && (cid != NULL ? UUID_eq(*cid, b.cid) : true) 120 + && (seq != NULL ? *seq == b.seq : true)) { 110 121 out = ListBlock_cons(b, out); 111 122 } 112 123 } ··· 150 161 print_uuid(block.nid); 151 162 printf(", cid: "); 152 163 print_uuid(block.nid); 153 - printf("\n)"); 164 + printf(", seq: %zu\n", block.seq); 154 165 }
+3 -2
src/lib/block.h
··· 26 26 UUID fid; ///< File ID (foreign from INode) default 0 27 27 UUID nid; ///< Node ID (foreign from DNode) default 0 28 28 UUID cid; ///< Chunk ID default "" 29 + size_t seq; ///< The order of this chunk 29 30 } Block; 30 31 31 32 DefList(Block) ··· 65 66 /// @param fid UUID of file's INode or NULL 66 67 /// @param nid UUID of DNode or NULL 67 68 /// @param cid string representing Block's chunk ID or NULL 68 - void insert_into_block(UUID* fid, UUID* nid, UUID* cid); 69 + void insert_into_block(UUID* fid, UUID* nid, UUID* cid, size_t* seq); 69 70 70 71 /// SELECT from the Block table. 71 72 /// ··· 74 75 /// @param nid the Block's DNode's UUID or NULL 75 76 /// @param cid the Block's chunk ID or NULL 76 77 /// @return a ListBlock of the possible matches 77 - ListBlock select_from_block(UUID* bid, UUID* fid, UUID* nid, UUID* cid); 78 + ListBlock select_from_block(UUID* bid, UUID* fid, UUID* nid, UUID* cid, size_t* seq); 78 79 79 80 /// Get the Block table from the database. 80 81 ///
+7 -7
src/lib/dnode.c
··· 4 4 ImplList(DNodeInfo) 5 5 6 6 Buffer DNodeInfo_serialize(DNodeInfo dinfo) { 7 - return concat(IPv4_serialize(dinfo.address), concat(UUID_serialize(dinfo.cid), Port_serialize(dinfo.port))); 7 + return concat(DNode_serialize(dinfo.dnode), concat(UUID_serialize(dinfo.cid), size_t_serialize(dinfo.seq))); 8 8 } 9 9 10 10 DNodeInfo DNodeInfo_deserialize(Buffer buf) { 11 - IPv4 address = IPv4_deserialize((Buffer){ .buf = buf.buf, .len = sizeof(IPv4) }); 12 - UUID cid = UUID_deserialize((Buffer){ .buf = buf.buf + sizeof(IPv4), .len = sizeof(UUID) }); 13 - Port port = Port_deserialize((Buffer){ .buf = buf.buf + sizeof(IPv4) + sizeof(UUID), .len = sizeof(Port)}); 11 + DNode dnode = DNode_deserialize((Buffer){ .buf = buf.buf, .len = sizeof(UUID) + sizeof(IPv4) + sizeof(Port) }); 12 + UUID cid = UUID_deserialize((Buffer){ .buf = buf.buf + sizeof(UUID) + sizeof(IPv4) + sizeof(Port), .len = sizeof(UUID) }); 13 + size_t seq = size_t_deserialize((Buffer){ .buf = buf.buf + sizeof(UUID) + sizeof(IPv4) + sizeof(Port) + sizeof(UUID), .len = sizeof(size_t)}); 14 14 15 15 return (DNodeInfo){ 16 - .address = address, 16 + .dnode = dnode, 17 17 .cid = cid, 18 - .port = port 18 + .seq = seq, 19 19 }; 20 20 } 21 21 ··· 32 32 33 33 ListDNodeInfo ListDNodeInfo_deserialize(Buffer buf) { 34 34 ListDNodeInfo out = NULL; 35 - for (size_t len = 0; len < buf.len; len += sizeof(IPv4) + sizeof(UUID) + sizeof(Port)) { 35 + for (size_t len = 0; len < buf.len; len += sizeof(UUID) + sizeof(IPv4) + sizeof(Port) + sizeof(UUID) + sizeof(size_t)) { 36 36 out = ListDNodeInfo_cons(DNodeInfo_deserialize((Buffer){ 37 37 .len = 0, // INFO: this does not have to be set. 38 38 .buf = buf.buf + len,
+8 -7
src/lib/dnode.h
··· 30 30 Port port; ///< Port of where the connection came from 31 31 } DNode; 32 32 33 - DefList(DNode) 34 33 34 + /// This carries all the necessary information that a chunk should have. 35 35 typedef struct { 36 - IPv4 address; 37 - Port port; 38 - UUID cid; 36 + DNode dnode; ///< the DNode of the chunk 37 + UUID cid; ///< The UUID of the chunk 38 + size_t seq; ///< The place in the sequence of chunks where this chunk should be 39 39 } DNodeInfo; 40 40 41 + DefList(DNodeInfo) 42 + 43 + DefList(DNode) 44 + 41 45 Buffer DNodeInfo_serialize(DNodeInfo dinfo); 42 46 43 47 DNodeInfo DNodeInfo_deserialize(Buffer buf); 44 48 45 - DefList(DNodeInfo) 46 - 47 49 Buffer ListDNodeInfo_serialize(ListDNodeInfo list); 48 50 49 51 ListDNodeInfo ListDNodeInfo_deserialize(Buffer buf); 50 - 51 52 52 53 /// Serialize a DNode into a Buffer. 53 54 /// Caller must free memory in Buffer.buf.
+14 -2
src/lib/enchufe.c
··· 156 156 return concat(Tag_serialize(command.tag), concat(size_t_serialize(command.as.put.fsize), SafeStr_serialize(command.as.put.fname))); 157 157 case WRITE: 158 158 return concat(Tag_serialize(command.tag), size_t_serialize(command.as.write.nbytes)); 159 + case READ: 160 + return concat(Tag_serialize(command.tag), UUID_serialize(command.as.read.cid)); 159 161 default: 160 162 fprintf(stderr, "ERROR: Tried to serialize a command in a wrong way.\n"); 161 163 exit(1); ··· 192 194 .fname = SafeStr_deserialize((Buffer){ .buf = buf.buf + sizeof(enum Tag) + sizeof(size_t), .len = 0 }), 193 195 } 194 196 }; 195 - case WRITE: { 197 + case WRITE: 196 198 return (Command){ 197 199 .tag = tag, 198 200 .as.write.nbytes = size_t_deserialize((Buffer){ .buf = buf.buf + sizeof(enum Tag), .len = sizeof(size_t)}), 199 201 }; 200 - } break; 202 + case READ: { 203 + // INFO: This is necessary to avoid the padding that the C compiler 204 + // introduces. This padding shows up in sizeof() but not in the 205 + // Buffer itself. 206 + Buffer tmp = UUID_serialize((UUID){0}); 207 + free(tmp.buf); 208 + return (Command){ 209 + .tag = tag, 210 + .as.read.cid = UUID_deserialize((Buffer){ .buf = buf.buf + sizeof(enum Tag), .len = tmp.len }), 211 + }; 212 + } break; 201 213 default: 202 214 fprintf(stderr, "ERROR: Tried to serialize a command in a wrong way.\n"); 203 215 exit(1);
+5
src/lib/enchufe.h
··· 17 17 #include <string.h> 18 18 #include <sys/socket.h> 19 19 #include "lib.h" 20 + #include "uuid.h" 20 21 21 22 /* ----- Types ----- */ 22 23 ··· 55 56 GET, 56 57 PUT, 57 58 WRITE, 59 + READ, 58 60 } tag ; 59 61 union { 60 62 struct { ··· 71 73 struct { 72 74 size_t nbytes; 73 75 } write; 76 + struct { 77 + UUID cid; 78 + } read; 74 79 } as ; 75 80 } Command; 76 81
+3 -3
src/meta-data.c
··· 73 73 ListINode_deinit(inodes); 74 74 free((void*)cmd.as.put.fname.str); 75 75 76 - printf("INFO: Waiting for copy client to respond with data node UUID's.\n"); 77 76 78 77 Byte buf[BUF_LEN] = {0}; 79 78 Buffer outside_buf = { .buf = buf, .len = BUF_LEN }; 79 + printf("INFO: Waiting for copy client to respond with data node UUID's.\n"); 80 80 size_t len = recibe(cliente, outside_buf); 81 81 outside_buf.len = len; 82 82 ListDNodeInfo dinfo = ListDNodeInfo_deserialize(outside_buf); 83 83 exists(dinfo); 84 84 for (ListDNodeInfo lptr = dinfo; lptr != NULL; lptr = lptr->rest) { 85 85 DNodeInfo d = lptr->head; 86 - ListDNode dptr = select_from_dnode(NULL, &d.address, &d.port); 86 + ListDNode dptr = select_from_dnode(NULL, &d.dnode.address, &d.dnode.port); 87 87 exists(dptr); 88 88 UUID nid = dptr->head.nid; 89 - insert_into_block(&fid, &nid, &d.cid); 89 + insert_into_block(&fid, &nid, &d.cid, &d.seq); 90 90 } 91 91 } 92 92
+2 -2
src/testdb.c
··· 100 100 DNode* dnode = check_node(p.address, p.port); 101 101 if (dnode != NULL) { 102 102 // insert into block (nid, fid, cid) values (nid, fid, chunkid) 103 - insert_into_block(&fid, &dnode->nid, &p.chunkid); 103 + insert_into_block(&fid, &dnode->nid, &p.chunkid, NULL); 104 104 free(dnode); 105 105 return add_block_to_inode(fname, params->rest); 106 106 } else { ··· 147 147 148 148 ListBlockLocation out = NULL; 149 149 if (inode != NULL) { 150 - ListBlock block_matches = select_from_block(NULL, &inode->fid, NULL, NULL); 150 + ListBlock block_matches = select_from_block(NULL, &inode->fid, NULL, NULL, NULL); 151 151 152 152 assert(block_matches != NULL); 153 153 for (ListBlock bptr = block_matches; bptr != NULL; bptr = bptr->rest) {