1 /*
2 Copyright 2005-2010 Jakub Kruszona-Zawadzki, Gemius SA, 2013-2014 EditShare, 2013-2015 Skytechnology sp. z o.o..
3
4 This file was part of MooseFS and is part of LizardFS.
5
6 LizardFS is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, version 3.
9
10 LizardFS is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with LizardFS If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "common/platform.h"
20 #include "mount/mastercomm.h"
21
22 #include <limits.h>
23 #include <pthread.h>
24 #include <signal.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29 #include <unistd.h>
30 #include <atomic>
31 #include <condition_variable>
32 #include <mutex>
33 #include <unordered_map>
34 #include <vector>
35
36 #ifndef _WIN32
37 #include <arpa/inet.h>
38 #include <grp.h>
39 #include <pwd.h>
40 #endif
41
42 #include "common/datapack.h"
43 #include "common/exception.h"
44 #include "common/exit_status.h"
45 #include "common/goal.h"
46 #include "common/lizardfs_version.h"
47 #include "common/md5.h"
48 #include "common/mfserr.h"
49 #include "common/sockets.h"
50 #include "common/slogger.h"
51 #include "mount/exports.h"
52 #include "mount/stats.h"
53 #include "protocol/cltoma.h"
54 #include "protocol/matocl.h"
55 #include "protocol/MFSCommunication.h"
56 #include "protocol/packet.h"
57
58 struct threc {
59 pthread_t thid;
60 std::mutex mutex;
61 std::condition_variable condition;
62 MessageBuffer outputBuffer;
63 MessageBuffer inputBuffer;
64 uint8_t status; // receive status
65 bool sent; // packet was sent
66 bool received; // packet was received
67 bool waiting; // thread is waiting for answer
68
69 uint32_t receivedType;
70
71 uint32_t packetId; // thread number
72 threc *next;
73 };
74
75 typedef struct _acquired_file {
76 uint32_t inode;
77 uint32_t cnt;
78 struct _acquired_file *next;
79 } acquired_file;
80
81
82 #define DEFAULT_OUTPUT_BUFFSIZE 0x1000
83 #define DEFAULT_INPUT_BUFFSIZE 0x10000
84
85 #define RECEIVE_TIMEOUT 10
86
87 static threc *threchead=NULL;
88
89 static acquired_file *afhead=NULL;
90
91 static int fd;
92 static bool disconnect;
93 static time_t lastwrite;
94 static int sessionlost;
95
96 static uint32_t maxretries;
97
98 static pthread_t rpthid,npthid;
99 static std::mutex fdMutex, recMutex, acquiredFileMutex;
100
101 static uint32_t sessionid;
102 static uint32_t masterversion;
103
104 static char masterstrip[17];
105 static uint32_t masterip=0;
106 static uint16_t masterport=0;
107 static char srcstrip[17];
108 static uint32_t srcip=0;
109
110 static uint8_t fterm;
111 static std::atomic<bool> gIsKilled(false);
112
113 typedef std::unordered_map<PacketHeader::Type, PacketHandler*> PerTypePacketHandlers;
114 static PerTypePacketHandlers perTypePacketHandlers;
115 static std::mutex perTypePacketHandlersLock;
116
fs_getmasterlocation(uint8_t loc[14])117 void fs_getmasterlocation(uint8_t loc[14]) {
118 put32bit(&loc,masterip);
119 put16bit(&loc,masterport);
120 put32bit(&loc,sessionid);
121 put32bit(&loc,masterversion);
122 }
123
fs_getsrcip()124 uint32_t fs_getsrcip() {
125 return srcip;
126 }
127
128 enum {
129 MASTER_CONNECTS = 0,
130 MASTER_BYTESSENT,
131 MASTER_BYTESRCVD,
132 MASTER_PACKETSSENT,
133 MASTER_PACKETSRCVD,
134 STATNODES
135 };
136
137 static uint64_t *statsptr[STATNODES];
138
139 struct InitParams {
140 std::string bind_host;
141 std::string host;
142 std::string port;
143 bool meta;
144 bool do_not_remember_password;
145 std::string mountpoint;
146 std::string subfolder;
147 std::vector<uint8_t> password_digest;
148 unsigned report_reserved_period;
149
operator =InitParams150 InitParams &operator=(const LizardClient::FsInitParams ¶ms) {
151 bind_host = params.bind_host;
152 host = params.host;
153 port = params.port;
154 meta = params.meta;
155 do_not_remember_password = params.do_not_remember_password;
156 mountpoint = params.mountpoint;
157 subfolder = params.subfolder;
158 password_digest = params.password_digest;
159 report_reserved_period = params.report_reserved_period;
160 return *this;
161 }
162 };
163
164 static InitParams gInitParams;
165
master_statsptr_init(void)166 void master_statsptr_init(void) {
167 void *s;
168 s = stats_get_subnode(NULL,"master",0);
169 statsptr[MASTER_PACKETSRCVD] = stats_get_counterptr(stats_get_subnode(s,"packets_received",0));
170 statsptr[MASTER_PACKETSSENT] = stats_get_counterptr(stats_get_subnode(s,"packets_sent",0));
171 statsptr[MASTER_BYTESRCVD] = stats_get_counterptr(stats_get_subnode(s,"bytes_received",0));
172 statsptr[MASTER_BYTESSENT] = stats_get_counterptr(stats_get_subnode(s,"bytes_sent",0));
173 statsptr[MASTER_CONNECTS] = stats_get_counterptr(stats_get_subnode(s,"reconnects",0));
174 }
175
master_stats_inc(uint8_t id)176 void master_stats_inc(uint8_t id) {
177 if (id<STATNODES) {
178 stats_lock();
179 (*statsptr[id])++;
180 stats_unlock();
181 }
182 }
183
master_stats_add(uint8_t id,uint64_t s)184 void master_stats_add(uint8_t id,uint64_t s) {
185 if (id<STATNODES) {
186 stats_lock();
187 (*statsptr[id])+=s;
188 stats_unlock();
189 }
190 }
191
setDisconnect(bool value)192 static inline void setDisconnect(bool value) {
193 std::unique_lock<std::mutex> fdLock(fdMutex);
194 disconnect = value;
195 }
196
fs_inc_acnt(uint32_t inode)197 void fs_inc_acnt(uint32_t inode) {
198 acquired_file *afptr,**afpptr;
199 std::unique_lock<std::mutex> acquiredFileLock(acquiredFileMutex);
200 afpptr = &afhead;
201 while ((afptr=*afpptr)) {
202 if (afptr->inode==inode) {
203 afptr->cnt++;
204 return;
205 }
206 if (afptr->inode>inode) {
207 break;
208 }
209 afpptr = &(afptr->next);
210 }
211 afptr = (acquired_file*)malloc(sizeof(acquired_file));
212 afptr->inode = inode;
213 afptr->cnt = 1;
214 afptr->next = *afpptr;
215 *afpptr = afptr;
216 }
217
fs_dec_acnt(uint32_t inode)218 void fs_dec_acnt(uint32_t inode) {
219 acquired_file *afptr,**afpptr;
220 std::unique_lock<std::mutex> afLock(acquiredFileMutex);
221 afpptr = &afhead;
222 while ((afptr=*afpptr)) {
223 if (afptr->inode == inode) {
224 if (afptr->cnt<=1) {
225 *afpptr = afptr->next;
226 free(afptr);
227 } else {
228 afptr->cnt--;
229 }
230 return;
231 }
232 afpptr = &(afptr->next);
233 }
234 }
235
fs_get_my_threc()236 threc* fs_get_my_threc() {
237 pthread_t mythid = pthread_self();
238 threc *rec;
239 std::unique_lock<std::mutex> recLock(recMutex);
240 for (rec = threchead ; rec ; rec = rec->next) {
241 if (pthread_equal(rec->thid, mythid)) {
242 return rec;
243 }
244 }
245 rec = new threc;
246 rec->thid = mythid;
247 rec->sent = false;
248 rec->status = 0;
249 rec->received = false;
250 rec->waiting = 0;
251 rec->receivedType = 0;
252 if (threchead==NULL) {
253 rec->packetId = 1;
254 } else {
255 rec->packetId = threchead->packetId + 1;
256 }
257 rec->next = threchead;
258 threchead = rec;
259 return rec;
260 }
261
fs_get_threc_by_id(uint32_t packetId)262 threc* fs_get_threc_by_id(uint32_t packetId) {
263 threc *rec;
264 std::unique_lock<std::mutex> recLock(recMutex);
265 for (rec = threchead ; rec ; rec=rec->next) {
266 if (rec->packetId==packetId) {
267 return rec;
268 }
269 }
270 return NULL;
271 }
272
fs_createpacket(threc * rec,uint32_t cmd,uint32_t size)273 uint8_t* fs_createpacket(threc *rec,uint32_t cmd,uint32_t size) {
274 uint8_t *ptr;
275 uint32_t hdrsize = size+4;
276 std::unique_lock<std::mutex> lock(rec->mutex);
277 rec->outputBuffer.resize(size+12);
278 ptr = rec->outputBuffer.data();
279 put32bit(&ptr,cmd);
280 put32bit(&ptr,hdrsize);
281 put32bit(&ptr,rec->packetId);
282 return ptr;
283 }
284
fs_lizcreatepacket(threc * rec,MessageBuffer message)285 bool fs_lizcreatepacket(threc *rec, MessageBuffer message) {
286 std::unique_lock<std::mutex> lock(rec->mutex);
287 rec->outputBuffer = std::move(message);
288 return true;
289 }
290
291 LIZARDFS_CREATE_EXCEPTION_CLASS_MSG(LostSessionException, Exception, "session lost");
292
fs_threc_flush(threc * rec)293 static bool fs_threc_flush(threc *rec) {
294 std::unique_lock<std::mutex> fdLock(fdMutex);
295 if (sessionlost) {
296 throw LostSessionException();
297 }
298 if (fd==-1) {
299 return false;
300 }
301 std::unique_lock<std::mutex> lock(rec->mutex);
302 const int32_t size = rec->outputBuffer.size();
303 if (tcptowrite(fd, rec->outputBuffer.data(), size, 1000) != size) {
304 lzfs_pretty_syslog(LOG_WARNING, "tcp send error: %s", strerr(tcpgetlasterror()));
305 disconnect = true;
306 return false;
307 }
308 rec->received = false;
309 rec->sent = true;
310 lock.unlock();
311 master_stats_add(MASTER_BYTESSENT, size);
312 master_stats_inc(MASTER_PACKETSSENT);
313 lastwrite = time(NULL);
314 return true;
315 }
316
fs_threc_wait(threc * rec,std::unique_lock<std::mutex> & lock)317 static bool fs_threc_wait(threc *rec, std::unique_lock<std::mutex>& lock) {
318 while (!rec->received) {
319 rec->waiting = 1;
320 rec->condition.wait(lock);
321 rec->waiting = 0;
322 }
323 return rec->status == LIZARDFS_STATUS_OK;
324 }
325
sleep_time(uint32_t tryNo)326 static inline uint32_t sleep_time(uint32_t tryNo) {
327 if (tryNo < 30) {
328 return 1 + (tryNo) / 3;
329 } else {
330 return 10;
331 }
332 }
333
334 // TODO(jotek): not every request should be retransmitted if recv failed (e.g. snapshot)
fs_threc_send_receive(threc * rec,bool filter,PacketHeader::Type expected_type)335 static bool fs_threc_send_receive(threc *rec, bool filter, PacketHeader::Type expected_type) {
336 try {
337 for (uint32_t cnt = 0 ; cnt < maxretries ; cnt++) {
338 if (fs_threc_flush(rec)) {
339 std::unique_lock<std::mutex> lock(rec->mutex);
340 if (fs_threc_wait(rec, lock)) {
341 if (!filter || rec->receivedType == expected_type) {
342 return true;
343 } else {
344 lock.unlock();
345 setDisconnect(true);
346 }
347 }
348 }
349 sleep(sleep_time(cnt));
350 continue;
351 }
352 } catch (LostSessionException&) {
353 }
354 return false;
355 }
356
fs_sendandreceive(threc * rec,uint32_t expected_cmd,uint32_t * answer_leng)357 const uint8_t* fs_sendandreceive(threc *rec, uint32_t expected_cmd, uint32_t *answer_leng) {
358 // this function is only for compatibility with MooseFS code
359 sassert(expected_cmd <= PacketHeader::kMaxOldPacketType);
360 if (fs_threc_send_receive(rec, true, expected_cmd)) {
361 const uint8_t *answer;
362 answer = rec->inputBuffer.data();
363 *answer_leng = rec->inputBuffer.size();
364
365 // MooseFS code doesn't expect message id, skip it
366 answer += 4;
367 *answer_leng -= 4;
368
369 return answer;
370 }
371 return NULL;
372 }
373
fs_lizsendandreceive(threc * rec,uint32_t expectedCommand,MessageBuffer & messageData)374 bool fs_lizsendandreceive(threc *rec, uint32_t expectedCommand, MessageBuffer& messageData) {
375 if (fs_threc_send_receive(rec, true, expectedCommand)) {
376 std::unique_lock<std::mutex> lock(rec->mutex);
377 rec->received = false; // we steal ownership of the received buffer
378 messageData = std::move(rec->inputBuffer);
379 return true;
380 }
381 return false;
382 }
383
fs_lizsend(threc * rec)384 bool fs_lizsend(threc *rec) {
385 try {
386 for (uint32_t cnt = 0; cnt < maxretries; cnt++) {
387 if (fs_threc_flush(rec)) {
388 return true;
389 }
390 sleep(sleep_time(cnt));
391 }
392 } catch (LostSessionException&) {
393 }
394 return false;
395 }
396
fs_lizrecv(threc * rec,uint32_t expectedCommand,MessageBuffer & messageData)397 bool fs_lizrecv(threc *rec, uint32_t expectedCommand, MessageBuffer& messageData) {
398 try {
399 std::unique_lock<std::mutex> lock(rec->mutex);
400 if (fs_threc_wait(rec, lock)) {
401 if (rec->receivedType == expectedCommand) {
402 rec->received = false; // we steal ownership of the received buffer
403 messageData = std::move(rec->inputBuffer);
404 return true;
405 } else {
406 lock.unlock();
407 setDisconnect(true);
408 }
409 }
410 } catch (LostSessionException&) {
411 }
412 return false;
413 }
414
fs_lizsendandreceive_any(threc * rec,MessageBuffer & messageData)415 bool fs_lizsendandreceive_any(threc *rec, MessageBuffer& messageData) {
416 if (fs_threc_send_receive(rec, false, 0)) {
417 std::unique_lock<std::mutex> lock(rec->mutex);
418 const MessageBuffer& payload = rec->inputBuffer;
419 const PacketHeader header(rec->receivedType, payload.size());
420 messageData.clear();
421 serialize(messageData, header);
422 messageData.insert(messageData.end(), payload.begin(), payload.end());
423 return true;
424 }
425 return false;
426 }
427
fs_resolve(bool verbose,const std::string & bindhostname,const std::string & masterhostname,const std::string & masterportname)428 int fs_resolve(bool verbose, const std::string &bindhostname, const std::string &masterhostname, const std::string &masterportname) {
429 if (!bindhostname.empty()) {
430 if (tcpresolve(bindhostname.c_str(), nullptr, &srcip, nullptr, 1) < 0) {
431 if (verbose) {
432 fprintf(stderr,"can't resolve source hostname (%s)\n", bindhostname.c_str());
433 } else {
434 lzfs_pretty_syslog(LOG_WARNING,"can't resolve source hostname (%s)", bindhostname.c_str());
435 }
436 return -1;
437 }
438 } else {
439 srcip = 0;
440 }
441 snprintf(srcstrip, 17, "%" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32,
442 (srcip>>24)&0xFF, (srcip>>16)&0xFF, (srcip>>8)&0xFF, srcip&0xFF);
443 srcstrip[16] = 0;
444
445 if (tcpresolve(masterhostname.c_str(), masterportname.c_str(), &masterip, &masterport, 0) < 0) {
446 if (verbose) {
447 fprintf(stderr, "can't resolve master hostname and/or portname (%s:%s)\n",
448 masterhostname.c_str(), masterportname.c_str());
449 } else {
450 lzfs_pretty_syslog(LOG_WARNING,"can't resolve master hostname and/or portname (%s:%s)",
451 masterhostname.c_str(), masterportname.c_str());
452 }
453 return -1;
454 }
455 snprintf(masterstrip, 17, "%" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32,
456 (masterip>>24)&0xFF, (masterip>>16)&0xFF, (masterip>>8)&0xFF, masterip&0xFF);
457 masterstrip[16] = 0;
458
459 return 0;
460 }
461
fs_connect(bool verbose)462 int fs_connect(bool verbose) {
463 uint32_t i,j;
464 uint8_t *wptr,*regbuff;
465 md5ctx ctx;
466 uint8_t digest[16];
467 const uint8_t *rptr;
468 uint8_t havepassword;
469 uint32_t pleng,ileng;
470 uint8_t sesflags;
471 uint32_t rootuid,rootgid,mapalluid,mapallgid;
472 uint8_t mingoal,maxgoal;
473 uint32_t mintrashtime,maxtrashtime;
474 const char *sesflagposstrtab[]={SESFLAG_POS_STRINGS};
475 const char *sesflagnegstrtab[]={SESFLAG_NEG_STRINGS};
476
477 if (fs_resolve(verbose ,gInitParams.bind_host, gInitParams.host, gInitParams.port) < 0) {
478 return -1;
479 }
480
481 havepassword = !gInitParams.password_digest.empty();
482 ileng=gInitParams.mountpoint.size() + 1;
483 if (gInitParams.meta) {
484 pleng=0;
485 regbuff = (uint8_t*) malloc(8+64+9+ileng+16);
486 } else {
487 pleng=gInitParams.subfolder.size() + 1;
488 regbuff = (uint8_t*) malloc(8+64+13+pleng+ileng+16);
489 }
490
491 fd = tcpsocket();
492 if (fd<0) {
493 free(regbuff);
494 return -1;
495 }
496 if (tcpnodelay(fd)<0) {
497 if (verbose) {
498 fprintf(stderr,"can't set TCP_NODELAY\n");
499 } else {
500 lzfs_pretty_syslog(LOG_WARNING,"can't set TCP_NODELAY");
501 }
502 }
503 if (srcip>0) {
504 if (tcpnumbind(fd,srcip,0)<0) {
505 if (verbose) {
506 fprintf(stderr,"can't bind socket to given ip (\"%s\")\n",srcstrip);
507 } else {
508 lzfs_pretty_syslog(LOG_WARNING,"can't bind socket to given ip (\"%s\")",srcstrip);
509 }
510 tcpclose(fd);
511 fd=-1;
512 free(regbuff);
513 return -1;
514 }
515 }
516 if (tcpnumconnect(fd,masterip,masterport)<0) {
517 if (verbose) {
518 fprintf(stderr,"can't connect to mfsmaster (\"%s\":\"%" PRIu16 "\")\n",masterstrip,masterport);
519 } else {
520 lzfs_pretty_syslog(LOG_WARNING,"can't connect to mfsmaster (\"%s\":\"%" PRIu16 "\")",masterstrip,masterport);
521 }
522 tcpclose(fd);
523 fd=-1;
524 free(regbuff);
525 return -1;
526 }
527 if (havepassword) {
528 wptr = regbuff;
529 put32bit(&wptr,CLTOMA_FUSE_REGISTER);
530 put32bit(&wptr,65);
531 memcpy(wptr,FUSE_REGISTER_BLOB_ACL,64);
532 wptr+=64;
533 put8bit(&wptr,REGISTER_GETRANDOM);
534 if (tcptowrite(fd,regbuff,8+65,1000)!=8+65) {
535 if (verbose) {
536 fprintf(stderr,"error sending data to mfsmaster\n");
537 } else {
538 lzfs_pretty_syslog(LOG_WARNING,"error sending data to mfsmaster");
539 }
540 tcpclose(fd);
541 fd=-1;
542 free(regbuff);
543 return -1;
544 }
545 if (tcptoread(fd,regbuff,8,1000)!=8) {
546 if (verbose) {
547 fprintf(stderr,"error receiving data from mfsmaster\n");
548 } else {
549 lzfs_pretty_syslog(LOG_WARNING,"error receiving data from mfsmaster");
550 }
551 tcpclose(fd);
552 fd=-1;
553 free(regbuff);
554 return -1;
555 }
556 rptr = regbuff;
557 i = get32bit(&rptr);
558 if (i!=MATOCL_FUSE_REGISTER) {
559 if (verbose) {
560 fprintf(stderr,"got incorrect answer from mfsmaster\n");
561 } else {
562 lzfs_pretty_syslog(LOG_WARNING,"got incorrect answer from mfsmaster");
563 }
564 tcpclose(fd);
565 fd=-1;
566 free(regbuff);
567 return -1;
568 }
569 i = get32bit(&rptr);
570 if (i!=32) {
571 if (verbose) {
572 fprintf(stderr,"got incorrect answer from mfsmaster\n");
573 } else {
574 lzfs_pretty_syslog(LOG_WARNING,"got incorrect answer from mfsmaster");
575 }
576 tcpclose(fd);
577 fd=-1;
578 free(regbuff);
579 return -1;
580 }
581 if (tcptoread(fd,regbuff,32,1000)!=32) {
582 if (verbose) {
583 fprintf(stderr,"error receiving data from mfsmaster\n");
584 } else {
585 lzfs_pretty_syslog(LOG_WARNING,"error receiving data from mfsmaster");
586 }
587 tcpclose(fd);
588 fd=-1;
589 free(regbuff);
590 return -1;
591 }
592 md5_init(&ctx);
593 md5_update(&ctx,regbuff,16);
594 md5_update(&ctx, gInitParams.password_digest.data(), gInitParams.password_digest.size());
595 md5_update(&ctx,regbuff+16,16);
596 md5_final(digest,&ctx);
597 }
598 wptr = regbuff;
599 put32bit(&wptr,CLTOMA_FUSE_REGISTER);
600 if (gInitParams.meta) {
601 if (havepassword) {
602 put32bit(&wptr,64+9+ileng+16);
603 } else {
604 put32bit(&wptr,64+9+ileng);
605 }
606 } else {
607 if (havepassword) {
608 put32bit(&wptr,64+13+ileng+pleng+16);
609 } else {
610 put32bit(&wptr,64+13+ileng+pleng);
611 }
612 }
613 memcpy(wptr,FUSE_REGISTER_BLOB_ACL,64);
614 wptr+=64;
615 put8bit(&wptr,(gInitParams.meta)?REGISTER_NEWMETASESSION:REGISTER_NEWSESSION);
616 put16bit(&wptr,LIZARDFS_PACKAGE_VERSION_MAJOR);
617 put8bit(&wptr,LIZARDFS_PACKAGE_VERSION_MINOR);
618 put8bit(&wptr,LIZARDFS_PACKAGE_VERSION_MICRO);
619 put32bit(&wptr,ileng);
620 memcpy(wptr,gInitParams.mountpoint.c_str(),ileng);
621 wptr+=ileng;
622 if (!gInitParams.meta) {
623 put32bit(&wptr,pleng);
624 memcpy(wptr,gInitParams.subfolder.c_str(),pleng);
625 }
626 if (havepassword) {
627 memcpy(wptr+pleng,digest,16);
628 }
629 if (tcptowrite(fd,regbuff,8+64+(gInitParams.meta?9:13)+ileng+pleng+(havepassword?16:0),1000)!=(int32_t)(8+64+(gInitParams.meta?9:13)+ileng+pleng+(havepassword?16:0))) {
630 if (verbose) {
631 fprintf(stderr,"error sending data to mfsmaster: %s\n",strerr(tcpgetlasterror()));
632 } else {
633 lzfs_pretty_syslog(LOG_WARNING,"error sending data to mfsmaster: %s",strerr(tcpgetlasterror()));
634 }
635 tcpclose(fd);
636 fd=-1;
637 free(regbuff);
638 return -1;
639 }
640 if (tcptoread(fd,regbuff,8,1000)!=8) {
641 if (verbose) {
642 fprintf(stderr,"error receiving data from mfsmaster: %s\n",strerr(tcpgetlasterror()));
643 } else {
644 lzfs_pretty_syslog(LOG_WARNING,"error receiving data from mfsmaster: %s",strerr(tcpgetlasterror()));
645 }
646 tcpclose(fd);
647 fd=-1;
648 free(regbuff);
649 return -1;
650 }
651 rptr = regbuff;
652 i = get32bit(&rptr);
653 if (i!=MATOCL_FUSE_REGISTER) {
654 if (verbose) {
655 fprintf(stderr,"got incorrect answer from mfsmaster\n");
656 } else {
657 lzfs_pretty_syslog(LOG_WARNING,"got incorrect answer from mfsmaster");
658 }
659 tcpclose(fd);
660 fd=-1;
661 free(regbuff);
662 return -1;
663 }
664 i = get32bit(&rptr);
665 if (!(i==1 || (gInitParams.meta && (i==5 || i==9 || i==19)) || (gInitParams.meta==0 && (i==13 || i==21 || i==25 || i==35)))) {
666 if (verbose) {
667 fprintf(stderr,"got incorrect answer from mfsmaster\n");
668 } else {
669 lzfs_pretty_syslog(LOG_WARNING,"got incorrect answer from mfsmaster");
670 }
671 tcpclose(fd);
672 fd=-1;
673 free(regbuff);
674 return -1;
675 }
676 if (tcptoread(fd,regbuff,i,1000)!=(int32_t)i) {
677 if (verbose) {
678 fprintf(stderr,"error receiving data from mfsmaster: %s\n",strerr(tcpgetlasterror()));
679 } else {
680 lzfs_pretty_syslog(LOG_WARNING,"error receiving data from mfsmaster: %s",strerr(tcpgetlasterror()));
681 }
682 tcpclose(fd);
683 fd=-1;
684 free(regbuff);
685 return -1;
686 }
687 rptr = regbuff;
688 if (i==1) {
689 if (verbose) {
690 fprintf(stderr,"mfsmaster register error: %s\n",lizardfs_error_string(rptr[0]));
691 } else {
692 lzfs_pretty_syslog(LOG_WARNING,"mfsmaster register error: %s",lizardfs_error_string(rptr[0]));
693 }
694 tcpclose(fd);
695 fd=-1;
696 free(regbuff);
697 return -1;
698 }
699 if (i==9 || i==19 || i==25 || i==35) {
700 masterversion = get32bit(&rptr);
701 } else {
702 masterversion = 0;
703 }
704 sessionid = get32bit(&rptr);
705 sesflags = get8bit(&rptr);
706 if (!gInitParams.meta) {
707 rootuid = get32bit(&rptr);
708 rootgid = get32bit(&rptr);
709 if (i==21 || i==25 || i==35) {
710 mapalluid = get32bit(&rptr);
711 mapallgid = get32bit(&rptr);
712 } else {
713 mapalluid = 0;
714 mapallgid = 0;
715 }
716 } else {
717 rootuid = 0;
718 rootgid = 0;
719 mapalluid = 0;
720 mapallgid = 0;
721 }
722 if (i==19 || i==35) {
723 mingoal = get8bit(&rptr);
724 maxgoal = get8bit(&rptr);
725 mintrashtime = get32bit(&rptr);
726 maxtrashtime = get32bit(&rptr);
727 } else {
728 mingoal = 0;
729 maxgoal = 0;
730 mintrashtime = 0;
731 maxtrashtime = 0;
732 }
733 free(regbuff);
734 lastwrite=time(NULL);
735 if (!verbose) {
736 lzfs_pretty_syslog(LOG_NOTICE,"registered to master with new session (id #%" PRIu32 ")", sessionid);
737 }
738 if (gInitParams.do_not_remember_password) {
739 std::fill(gInitParams.password_digest.begin(), gInitParams.password_digest.end(), 0);
740 }
741 if (verbose) {
742 fprintf(stderr,"mfsmaster accepted connection with parameters: ");
743 j=0;
744 for (i=0 ; i<8 ; i++) {
745 if (sesflags&(1<<i)) {
746 fprintf(stderr,"%s%s",j?",":"",sesflagposstrtab[i]);
747 j=1;
748 } else if (sesflagnegstrtab[i]) {
749 fprintf(stderr,"%s%s",j?",":"",sesflagnegstrtab[i]);
750 j=1;
751 }
752 }
753 if (j==0) {
754 fprintf(stderr,"-");
755 }
756 if (!gInitParams.meta) {
757 #ifndef _WIN32
758 struct passwd pwd,*pw;
759 struct group grp,*gr;
760 char pwdgrpbuff[16384];
761
762 fprintf(stderr," ; root mapped to ");
763 getpwuid_r(rootuid,&pwd,pwdgrpbuff,16384,&pw);
764 if (pw) {
765 fprintf(stderr,"%s:",pw->pw_name);
766 } else {
767 fprintf(stderr,"%" PRIu32 ":",rootuid);
768 }
769 getgrgid_r(rootgid,&grp,pwdgrpbuff,16384,&gr);
770 if (gr) {
771 fprintf(stderr,"%s",gr->gr_name);
772 } else {
773 fprintf(stderr,"%" PRIu32,rootgid);
774 }
775 if (sesflags&SESFLAG_MAPALL) {
776 fprintf(stderr," ; users mapped to ");
777 pw = getpwuid(mapalluid);
778 if (pw) {
779 fprintf(stderr,"%s:",pw->pw_name);
780 } else {
781 fprintf(stderr,"%" PRIu32 ":",mapalluid);
782 }
783 gr = getgrgid(mapallgid);
784 if (gr) {
785 fprintf(stderr,"%s",gr->gr_name);
786 } else {
787 fprintf(stderr,"%" PRIu32,mapallgid);
788 }
789 }
790 #else
791 fprintf(stderr, " ; root mapped to %" PRIu32 ":%" PRIu32, rootuid, rootgid);
792 fprintf(stderr, " ; users mapped to %" PRIu32 ":%" PRIu32, mapalluid, mapallgid);
793 #endif
794 } else {
795 // meta
796 if (sesflags & SESFLAG_NONROOTMETA) {
797 nonRootAllowedToUseMeta() = true;
798 } else {
799 nonRootAllowedToUseMeta() = false;
800 }
801 }
802 if (mingoal>0 && maxgoal>0) {
803 if (mingoal > GoalId::kMin || maxgoal < GoalId::kMax) {
804 fprintf(stderr," ; setgoal limited to (%u:%u)",mingoal,maxgoal);
805 }
806 if (mintrashtime>0 || maxtrashtime<UINT32_C(0xFFFFFFFF)) {
807 fprintf(stderr," ; settrashtime limited to (");
808 if (mintrashtime>0) {
809 if (mintrashtime>604800) {
810 fprintf(stderr,"%uw",mintrashtime/604800);
811 mintrashtime %= 604800;
812 }
813 if (mintrashtime>86400) {
814 fprintf(stderr,"%ud",mintrashtime/86400);
815 mintrashtime %= 86400;
816 }
817 if (mintrashtime>3600) {
818 fprintf(stderr,"%uh",mintrashtime/3600);
819 mintrashtime %= 3600;
820 }
821 if (mintrashtime>60) {
822 fprintf(stderr,"%um",mintrashtime/60);
823 mintrashtime %= 60;
824 }
825 if (mintrashtime>0) {
826 fprintf(stderr,"%us",mintrashtime);
827 }
828 } else {
829 fprintf(stderr,"0s");
830 }
831 fprintf(stderr,":");
832 if (maxtrashtime>0) {
833 if (maxtrashtime>604800) {
834 fprintf(stderr,"%uw",maxtrashtime/604800);
835 maxtrashtime %= 604800;
836 }
837 if (maxtrashtime>86400) {
838 fprintf(stderr,"%ud",maxtrashtime/86400);
839 maxtrashtime %= 86400;
840 }
841 if (maxtrashtime>3600) {
842 fprintf(stderr,"%uh",maxtrashtime/3600);
843 maxtrashtime %= 3600;
844 }
845 if (maxtrashtime>60) {
846 fprintf(stderr,"%um",maxtrashtime/60);
847 maxtrashtime %= 60;
848 }
849 if (maxtrashtime>0) {
850 fprintf(stderr,"%us",maxtrashtime);
851 }
852 } else {
853 fprintf(stderr,"0s");
854 }
855 fprintf(stderr,")");
856 }
857 }
858 fprintf(stderr,"\n");
859 }
860 return 0;
861 }
862
fs_reconnect()863 void fs_reconnect() {
864 uint32_t i;
865 uint8_t *wptr,regbuff[8+64+9];
866 const uint8_t *rptr;
867
868 if (sessionid==0) {
869 lzfs_pretty_syslog(LOG_WARNING,"can't register: session not created");
870 return;
871 }
872
873 fd = tcpsocket();
874 if (fd<0) {
875 return;
876 }
877 if (tcpnodelay(fd)<0) {
878 lzfs_pretty_syslog(LOG_WARNING,"can't set TCP_NODELAY: %s",strerr(tcpgetlasterror()));
879 }
880 if (srcip>0) {
881 if (tcpnumbind(fd,srcip,0)<0) {
882 lzfs_pretty_syslog(LOG_WARNING,"can't bind socket to given ip (\"%s\")",srcstrip);
883 tcpclose(fd);
884 fd=-1;
885 return;
886 }
887 }
888 if (tcpnumconnect(fd,masterip,masterport)<0) {
889 lzfs_pretty_syslog(LOG_WARNING,"can't connect to master (\"%s\":\"%" PRIu16 "\")",masterstrip,masterport);
890 tcpclose(fd);
891 fd=-1;
892 return;
893 }
894 master_stats_inc(MASTER_CONNECTS);
895 wptr = regbuff;
896 put32bit(&wptr,CLTOMA_FUSE_REGISTER);
897 put32bit(&wptr,73);
898 memcpy(wptr,FUSE_REGISTER_BLOB_ACL,64);
899 wptr+=64;
900 put8bit(&wptr,REGISTER_RECONNECT);
901 put32bit(&wptr,sessionid);
902 put16bit(&wptr,LIZARDFS_PACKAGE_VERSION_MAJOR);
903 put8bit(&wptr,LIZARDFS_PACKAGE_VERSION_MINOR);
904 put8bit(&wptr,LIZARDFS_PACKAGE_VERSION_MICRO);
905 if (tcptowrite(fd,regbuff,8+64+9,1000)!=8+64+9) {
906 lzfs_pretty_syslog(LOG_WARNING,"master: register error (write: %s)",strerr(tcpgetlasterror()));
907 tcpclose(fd);
908 fd=-1;
909 return;
910 }
911 master_stats_add(MASTER_BYTESSENT,16+64);
912 master_stats_inc(MASTER_PACKETSSENT);
913 if (tcptoread(fd,regbuff,8,1000)!=8) {
914 lzfs_pretty_syslog(LOG_WARNING,"master: register error (read header: %s)",strerr(tcpgetlasterror()));
915 tcpclose(fd);
916 fd=-1;
917 return;
918 }
919 master_stats_add(MASTER_BYTESRCVD,8);
920 rptr = regbuff;
921 i = get32bit(&rptr);
922 if (i!=MATOCL_FUSE_REGISTER) {
923 lzfs_pretty_syslog(LOG_WARNING,"master: register error (bad answer: %" PRIu32 ")",i);
924 tcpclose(fd);
925 fd=-1;
926 return;
927 }
928 i = get32bit(&rptr);
929 if (i!=1) {
930 lzfs_pretty_syslog(LOG_WARNING,"master: register error (bad length: %" PRIu32 ")",i);
931 tcpclose(fd);
932 fd=-1;
933 return;
934 }
935 if (tcptoread(fd,regbuff,i,1000)!=(int32_t)i) {
936 lzfs_pretty_syslog(LOG_WARNING,"master: register error (read data: %s)",strerr(tcpgetlasterror()));
937 tcpclose(fd);
938 fd=-1;
939 return;
940 }
941 master_stats_add(MASTER_BYTESRCVD,i);
942 master_stats_inc(MASTER_PACKETSRCVD);
943 rptr = regbuff;
944 if (rptr[0]!=0) {
945 sessionlost=1;
946 lzfs_pretty_syslog(LOG_WARNING,"master: register status: %s",lizardfs_error_string(rptr[0]));
947 tcpclose(fd);
948 fd=-1;
949 return;
950 }
951 lastwrite=time(NULL);
952 lzfs_pretty_syslog(LOG_NOTICE,"registered to master (session id #%" PRIu32 ")", sessionid);
953 }
954
fs_close_session(void)955 void fs_close_session(void) {
956 uint8_t *wptr,regbuff[8+64+5];
957
958 if (sessionid==0) {
959 return;
960 }
961
962 wptr = regbuff;
963 put32bit(&wptr,CLTOMA_FUSE_REGISTER);
964 put32bit(&wptr,69);
965 memcpy(wptr,FUSE_REGISTER_BLOB_ACL,64);
966 wptr+=64;
967 put8bit(&wptr,REGISTER_CLOSESESSION);
968 put32bit(&wptr,sessionid);
969 if (tcptowrite(fd,regbuff,8+64+5,1000)!=8+64+5) {
970 lzfs_pretty_syslog(LOG_WARNING,"master: close session error (write: %s)",strerr(tcpgetlasterror()));
971 }
972 }
973
974 #ifdef ENABLE_EXIT_ON_USR1
usr1_handler(int)975 static void usr1_handler(int) {
976 gIsKilled = true;
977 }
978 #endif
979
fs_nop_thread(void * arg)980 void* fs_nop_thread(void *arg) {
981 uint8_t *ptr,hdr[12],*inodespacket;
982 int32_t inodesleng;
983 acquired_file *afptr;
984 int now;
985 uint32_t inodeswritecnt=0;
986 (void)arg;
987
988 #ifdef ENABLE_EXIT_ON_USR1
989 if (signal(SIGUSR1, usr1_handler) == SIG_ERR) {
990 mabort("Can't set handler for SIGUSR1");
991 }
992 #endif
993 for (;;) {
994 now = time(NULL);
995 std::unique_lock<std::mutex> fdLock(fdMutex);
996 if (fterm) {
997 if (fd>=0) {
998 fs_close_session();
999 }
1000 return NULL;
1001 }
1002 if (gIsKilled) {
1003 lzfs_pretty_syslog(LOG_NOTICE, "Received SIGUSR1, killing gently...");
1004 exit(LIZARDFS_EXIT_STATUS_GENTLY_KILL);
1005 }
1006 if (disconnect == false && fd >= 0) {
1007 if (lastwrite+2<now) { // NOP
1008 ptr = hdr;
1009 put32bit(&ptr,ANTOAN_NOP);
1010 put32bit(&ptr,4);
1011 put32bit(&ptr,0);
1012 if (tcptowrite(fd,hdr,12,1000)!=12) {
1013 disconnect = true;
1014 } else {
1015 master_stats_add(MASTER_BYTESSENT,12);
1016 master_stats_inc(MASTER_PACKETSSENT);
1017 }
1018 lastwrite=now;
1019 }
1020 if (++inodeswritecnt >= gInitParams.report_reserved_period) {
1021 inodeswritecnt = 0;
1022 std::unique_lock<std::mutex> asLock(acquiredFileMutex);
1023 inodesleng=8;
1024 for (afptr=afhead ; afptr ; afptr=afptr->next) {
1025 //lzfs_pretty_syslog(LOG_NOTICE,"reserved inode: %" PRIu32,afptr->inode);
1026 inodesleng+=4;
1027 }
1028 inodespacket = (uint8_t*) malloc(inodesleng);
1029 ptr = inodespacket;
1030 put32bit(&ptr,CLTOMA_FUSE_RESERVED_INODES);
1031 put32bit(&ptr,inodesleng-8);
1032 for (afptr=afhead ; afptr ; afptr=afptr->next) {
1033 put32bit(&ptr,afptr->inode);
1034 }
1035 if (tcptowrite(fd,inodespacket,inodesleng,1000)!=inodesleng) {
1036 disconnect = true;
1037 } else {
1038 master_stats_add(MASTER_BYTESSENT,inodesleng);
1039 master_stats_inc(MASTER_PACKETSSENT);
1040 }
1041 free(inodespacket);
1042 }
1043 }
1044 fdLock.unlock();
1045 sleep(1);
1046 }
1047 }
1048
fs_append_from_master(MessageBuffer & buffer,uint32_t size)1049 bool fs_append_from_master(MessageBuffer& buffer, uint32_t size) {
1050 if (size == 0) {
1051 return true;
1052 }
1053 const uint32_t oldSize = buffer.size();
1054 buffer.resize(oldSize + size);
1055 uint8_t *appendPointer = buffer.data() + oldSize;
1056 int r = tcptoread(fd, appendPointer, size, RECEIVE_TIMEOUT * 1000);
1057 if (r == 0) {
1058 lzfs_pretty_syslog(LOG_WARNING,"master: connection lost");
1059 setDisconnect(true);
1060 return false;
1061 }
1062 if (r != (int)size) {
1063 lzfs_pretty_syslog(LOG_WARNING,"master: tcp recv error: %s",strerr(tcpgetlasterror()));
1064 setDisconnect(true);
1065 return false;
1066 }
1067 master_stats_add(MASTER_BYTESRCVD, size);
1068 return true;
1069 }
1070
1071 template<class... Args>
fs_deserialize_from_master(uint32_t & remainingBytes,Args &...destination)1072 bool fs_deserialize_from_master(uint32_t& remainingBytes, Args&... destination) {
1073 const uint32_t size = serializedSize(destination...);
1074 if (size > remainingBytes) {
1075 lzfs_pretty_syslog(LOG_WARNING,"master: packet too short");
1076 setDisconnect(true);
1077 return false;
1078 }
1079 MessageBuffer buffer;
1080 if (!fs_append_from_master(buffer, size)) {
1081 return false;
1082 }
1083 try {
1084 deserialize(buffer, destination...);
1085 } catch (IncorrectDeserializationException& e) {
1086 lzfs_pretty_syslog(LOG_WARNING,"master: deserialization error: %s", e.what());
1087 setDisconnect(true);
1088 return false;
1089 }
1090 remainingBytes -= size;
1091 return true;
1092 }
1093
fs_receive_thread(void *)1094 void* fs_receive_thread(void *) {
1095 uint32_t initialReconnectSleep_ms = 100;
1096 uint32_t reconnectSleep_ms = initialReconnectSleep_ms;
1097 for (;;) {
1098 std::unique_lock<std::mutex>fdLock(fdMutex);
1099 if (fterm) {
1100 return NULL;
1101 }
1102 if (disconnect) {
1103 tcpclose(fd);
1104 fd=-1;
1105 disconnect = false;
1106 // send to any threc status error and unlock them
1107 std::unique_lock<std::mutex>recLock(recMutex);
1108 for (threc *rec=threchead ; rec ; rec=rec->next) {
1109 std::unique_lock<std::mutex> lock(rec->mutex);
1110 if (rec->sent) {
1111 rec->status = 1;
1112 rec->received = true;
1113 if (rec->waiting) {
1114 rec->condition.notify_one();
1115 }
1116 }
1117 }
1118 }
1119 if (fd==-1 && sessionid!=0) {
1120 fs_reconnect(); // try to register using the same session id
1121 }
1122 if (fd==-1) { // still not connected
1123 if (sessionlost) { // if previous session is lost then try to register as a new session
1124 if (fs_connect(false)==0) {
1125 sessionlost=0;
1126 }
1127 } else { // if other problem occurred then try to resolve hostname and portname then try to reconnect using the same session id
1128 if (fs_resolve(false, gInitParams.bind_host, gInitParams.host, gInitParams.port) == 0) {
1129 fs_reconnect();
1130 }
1131 }
1132 }
1133 if (fd==-1) {
1134 fdLock.unlock();
1135 usleep(reconnectSleep_ms * 1000);
1136 // slowly increase timeout before each retry
1137 if (reconnectSleep_ms < 5 * initialReconnectSleep_ms) {
1138 reconnectSleep_ms += initialReconnectSleep_ms / 2;
1139 } else if (reconnectSleep_ms < 10 * initialReconnectSleep_ms) {
1140 reconnectSleep_ms += initialReconnectSleep_ms;
1141 } else {
1142 reconnectSleep_ms = 20 * initialReconnectSleep_ms;
1143 }
1144 continue;
1145 } else {
1146 // connecection succeeded -- reset timeout the initial value
1147 reconnectSleep_ms = initialReconnectSleep_ms;
1148 }
1149 fdLock.unlock();
1150
1151 PacketHeader packetHeader;
1152 PacketVersion packetVersion;
1153 uint32_t messageId = 0;
1154 uint32_t remainingBytes = serializedSize(packetHeader);
1155 if (!fs_deserialize_from_master(remainingBytes, packetHeader)) {
1156 continue;
1157 }
1158 master_stats_inc(MASTER_PACKETSRCVD);
1159 remainingBytes = packetHeader.length;
1160
1161 {
1162 std::unique_lock<std::mutex> lock(perTypePacketHandlersLock);
1163 const PerTypePacketHandlers::iterator handler =
1164 perTypePacketHandlers.find(packetHeader.type);
1165 if (handler != perTypePacketHandlers.end()) {
1166 MessageBuffer buffer;
1167 if (fs_append_from_master(buffer, remainingBytes)) {
1168 handler->second->handle(std::move(buffer));
1169 }
1170 continue;
1171 }
1172 }
1173
1174 if (packetHeader.isLizPacketType()) {
1175 if (remainingBytes < serializedSize(packetVersion, messageId)) {
1176 lzfs_pretty_syslog(LOG_WARNING,"master: packet too short: no msgid");
1177 setDisconnect(true);
1178 continue;
1179 }
1180 if (!fs_deserialize_from_master(remainingBytes, packetVersion, messageId)) {
1181 continue;
1182 }
1183 } else {
1184 if (remainingBytes < serializedSize(messageId)) {
1185 lzfs_pretty_syslog(LOG_WARNING,"master: packet too short: no msgid");
1186 setDisconnect(true);
1187 continue;
1188 }
1189 if (!fs_deserialize_from_master(remainingBytes, messageId)) {
1190 continue;
1191 }
1192 }
1193
1194 if (messageId == 0) {
1195 if (packetHeader.type == ANTOAN_NOP && remainingBytes == 0) {
1196 continue;
1197 }
1198 if (packetHeader.type == ANTOAN_UNKNOWN_COMMAND ||
1199 packetHeader.type == ANTOAN_BAD_COMMAND_SIZE) {
1200 // just ignore these packets with packetId==0
1201 continue;
1202 }
1203 }
1204 threc *rec = fs_get_threc_by_id(messageId);
1205 if (rec == NULL) {
1206 lzfs_pretty_syslog(LOG_WARNING,"master: got unexpected queryid");
1207 setDisconnect(true);
1208 continue;
1209 }
1210 std::unique_lock<std::mutex> lock(rec->mutex);
1211 rec->inputBuffer.clear();
1212 if (packetHeader.isLizPacketType()) {
1213 serialize(rec->inputBuffer, packetVersion, messageId);
1214 } else {
1215 serialize(rec->inputBuffer, messageId);
1216 }
1217 if (!fs_append_from_master(rec->inputBuffer, remainingBytes)) {
1218 lock.unlock();
1219 continue;
1220 }
1221 rec->sent = false;
1222 rec->status = 0;
1223 rec->receivedType = packetHeader.type;
1224 rec->received = true;
1225 if (rec->waiting) {
1226 rec->condition.notify_one();
1227 }
1228 }
1229 }
1230
1231 // called before fork
fs_init_master_connection(LizardClient::FsInitParams & params)1232 int fs_init_master_connection(LizardClient::FsInitParams ¶ms) {
1233 master_statsptr_init();
1234
1235 gInitParams = params;
1236 std::fill(params.password_digest.begin(), params.password_digest.end(), 0);
1237
1238 fd = -1;
1239 sessionlost = params.delayed_init;
1240 sessionid = 0;
1241 disconnect = false;
1242
1243 if (params.delayed_init) {
1244 return 1;
1245 }
1246 return fs_connect(params.verbose);
1247 }
1248
1249 // called after fork
fs_init_threads(uint32_t retries)1250 void fs_init_threads(uint32_t retries) {
1251 pthread_attr_t thattr;
1252 maxretries = retries;
1253 fterm = 0;
1254
1255 pthread_attr_init(&thattr);
1256 pthread_attr_setstacksize(&thattr,0x100000);
1257 pthread_create(&rpthid,&thattr,fs_receive_thread,NULL);
1258 pthread_create(&npthid,&thattr,fs_nop_thread,NULL);
1259 pthread_attr_destroy(&thattr);
1260 }
1261
fs_term(void)1262 void fs_term(void) {
1263 threc *tr,*trn;
1264 acquired_file *af,*afn;
1265 std::unique_lock<std::mutex> fd_lock(fdMutex);
1266 fterm = 1;
1267 fd_lock.unlock();
1268 pthread_join(npthid,NULL);
1269 pthread_join(rpthid,NULL);
1270 std::unique_lock<std::mutex> rec_lock(recMutex);
1271 for (tr = threchead ; tr ; tr = trn) {
1272 trn = tr->next;
1273 tr->outputBuffer.clear();
1274 tr->inputBuffer.clear();
1275 delete tr;
1276 }
1277 threchead = nullptr;
1278 rec_lock.unlock();
1279 std::unique_lock<std::mutex> af_lock(acquiredFileMutex);
1280 for (af = afhead ; af ; af = afn) {
1281 afn = af->next;
1282 free(af);
1283 }
1284 afhead = nullptr;
1285 af_lock.unlock();
1286 fd_lock.lock();
1287 if (fd>=0) {
1288 tcpclose(fd);
1289 }
1290 }
1291
fs_got_inconsistent(const std::string & type,uint32_t size,const std::string & what)1292 static void fs_got_inconsistent(const std::string& type, uint32_t size, const std::string& what) {
1293 lzfs_pretty_syslog(LOG_NOTICE,
1294 "Got inconsistent %s message from master (length:%" PRIu32 "): %s",
1295 type.c_str(), size, what.c_str());
1296 setDisconnect(true);
1297 }
1298
fs_statfs(uint64_t * totalspace,uint64_t * availspace,uint64_t * trashspace,uint64_t * reservedspace,uint32_t * inodes)1299 void fs_statfs(uint64_t *totalspace,uint64_t *availspace,uint64_t *trashspace,uint64_t *reservedspace,uint32_t *inodes) {
1300 uint8_t *wptr;
1301 const uint8_t *rptr;
1302 uint32_t i;
1303 threc *rec = fs_get_my_threc();
1304 wptr = fs_createpacket(rec,CLTOMA_FUSE_STATFS,0);
1305 if (wptr==NULL) {
1306 *totalspace = 0;
1307 *availspace = 0;
1308 *trashspace = 0;
1309 *reservedspace = 0;
1310 *inodes = 0;
1311 return;
1312 }
1313 rptr = fs_sendandreceive(rec,MATOCL_FUSE_STATFS,&i);
1314 if (rptr==NULL || i!=36) {
1315 *totalspace = 0;
1316 *availspace = 0;
1317 *trashspace = 0;
1318 *reservedspace = 0;
1319 *inodes = 0;
1320 } else {
1321 *totalspace = get64bit(&rptr);
1322 *availspace = get64bit(&rptr);
1323 *trashspace = get64bit(&rptr);
1324 *reservedspace = get64bit(&rptr);
1325 *inodes = get32bit(&rptr);
1326 }
1327 }
1328
fs_access(uint32_t inode,uint32_t uid,uint32_t gid,uint8_t modemask)1329 uint8_t fs_access(uint32_t inode,uint32_t uid,uint32_t gid,uint8_t modemask) {
1330 uint8_t *wptr;
1331 const uint8_t *rptr;
1332 uint32_t i;
1333 uint8_t ret;
1334 threc *rec = fs_get_my_threc();
1335 wptr = fs_createpacket(rec,CLTOMA_FUSE_ACCESS,13);
1336 if (wptr==NULL) {
1337 return LIZARDFS_ERROR_IO;
1338 }
1339 put32bit(&wptr,inode);
1340 put32bit(&wptr,uid);
1341 put32bit(&wptr,gid);
1342 put8bit(&wptr,modemask);
1343 rptr = fs_sendandreceive(rec,MATOCL_FUSE_ACCESS,&i);
1344 if (!rptr || i!=1) {
1345 ret = LIZARDFS_ERROR_IO;
1346 } else {
1347 ret = rptr[0];
1348 }
1349 return ret;
1350 }
1351
fs_lookup(uint32_t parent,const std::string & path,uint32_t uid,uint32_t gid,uint32_t * inode,Attributes & attr)1352 uint8_t fs_lookup(uint32_t parent, const std::string &path, uint32_t uid, uint32_t gid, uint32_t *inode, Attributes &attr) {
1353 threc *rec = fs_get_my_threc();
1354 auto message = cltoma::wholePathLookup::build(rec->packetId, parent, path, uid, gid);
1355 if (!fs_lizcreatepacket(rec, message)) {
1356 return LIZARDFS_ERROR_IO;
1357 }
1358 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_WHOLE_PATH_LOOKUP, message)) {
1359 return LIZARDFS_ERROR_IO;
1360 }
1361 try {
1362 uint32_t msgid;
1363 PacketVersion packet_version;
1364 deserializePacketVersionNoHeader(message, packet_version);
1365 if (packet_version == matocl::wholePathLookup::kStatusPacketVersion) {
1366 uint8_t status;
1367 matocl::wholePathLookup::deserialize(message, msgid, status);
1368 if (status == LIZARDFS_STATUS_OK) {
1369 fs_got_inconsistent("LIZ_MATOCL_WHOLE_PATH_LOOKUP", message.size(),
1370 "version 0 and LIZARDFS_STATUS_OK");
1371 return LIZARDFS_ERROR_IO;
1372 }
1373 return status;
1374 } else if (packet_version == matocl::wholePathLookup::kResponsePacketVersion) {
1375 matocl::wholePathLookup::deserialize(message, msgid, *inode, attr);
1376 return LIZARDFS_STATUS_OK;
1377 } else {
1378 fs_got_inconsistent("LIZ_MATOCL_WHOLE_PATH_LOOKUP", message.size(),
1379 "unknown version " + std::to_string(packet_version));
1380 return LIZARDFS_ERROR_IO;
1381 }
1382 } catch (Exception& ex) {
1383 fs_got_inconsistent("LIZ_MATOCL_WHOLE_PATH_LOOKUP", message.size(), ex.what());
1384 return LIZARDFS_ERROR_IO;
1385 }
1386 }
1387
fs_getattr(uint32_t inode,uint32_t uid,uint32_t gid,Attributes & attr)1388 uint8_t fs_getattr(uint32_t inode, uint32_t uid, uint32_t gid, Attributes &attr) {
1389 uint8_t *wptr;
1390 const uint8_t *rptr;
1391 uint32_t i;
1392 uint8_t ret;
1393 threc *rec = fs_get_my_threc();
1394 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETATTR,12);
1395 if (wptr==NULL) {
1396 return LIZARDFS_ERROR_IO;
1397 }
1398 put32bit(&wptr,inode);
1399 put32bit(&wptr,uid);
1400 put32bit(&wptr,gid);
1401 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETATTR,&i);
1402 if (rptr==NULL) {
1403 ret = LIZARDFS_ERROR_IO;
1404 } else if (i==1) {
1405 ret = rptr[0];
1406 } else if (i != attr.size()) {
1407 setDisconnect(true);
1408 ret = LIZARDFS_ERROR_IO;
1409 } else {
1410 memcpy(attr.data(), rptr, attr.size());
1411 ret = LIZARDFS_STATUS_OK;
1412 }
1413 return ret;
1414 }
1415
fs_setattr(uint32_t inode,uint32_t uid,uint32_t gid,uint8_t setmask,uint16_t attrmode,uint32_t attruid,uint32_t attrgid,uint32_t attratime,uint32_t attrmtime,uint8_t sugidclearmode,Attributes & attr)1416 uint8_t fs_setattr(uint32_t inode, uint32_t uid, uint32_t gid, uint8_t setmask, uint16_t attrmode, uint32_t attruid, uint32_t attrgid, uint32_t attratime, uint32_t attrmtime, uint8_t sugidclearmode, Attributes &attr) {
1417 uint8_t *wptr;
1418 const uint8_t *rptr;
1419 uint32_t i;
1420 uint8_t ret;
1421 threc *rec = fs_get_my_threc();
1422 if (masterversion<0x010619) {
1423 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETATTR,31);
1424 } else {
1425 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETATTR,32);
1426 }
1427 if (wptr==NULL) {
1428 return LIZARDFS_ERROR_IO;
1429 }
1430 put32bit(&wptr,inode);
1431 put32bit(&wptr,uid);
1432 put32bit(&wptr,gid);
1433 put8bit(&wptr,setmask);
1434 put16bit(&wptr,attrmode);
1435 put32bit(&wptr,attruid);
1436 put32bit(&wptr,attrgid);
1437 put32bit(&wptr,attratime);
1438 put32bit(&wptr,attrmtime);
1439 if (masterversion>=0x010619) {
1440 put8bit(&wptr,sugidclearmode);
1441 }
1442 rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETATTR,&i);
1443 if (rptr==NULL) {
1444 ret = LIZARDFS_ERROR_IO;
1445 } else if (i==1) {
1446 ret = rptr[0];
1447 } else if (i != attr.size()) {
1448 setDisconnect(true);
1449 ret = LIZARDFS_ERROR_IO;
1450 } else {
1451 memcpy(attr.data(), rptr, attr.size());
1452 ret = LIZARDFS_STATUS_OK;
1453 }
1454 return ret;
1455 }
1456
fs_truncate(uint32_t inode,bool opened,uint32_t uid,uint32_t gid,uint64_t length,bool & clientPerforms,Attributes & attr,uint64_t & oldLength,uint32_t & lockId)1457 uint8_t fs_truncate(uint32_t inode, bool opened, uint32_t uid, uint32_t gid, uint64_t length,
1458 bool& clientPerforms, Attributes& attr, uint64_t& oldLength, uint32_t& lockId) {
1459 threc *rec = fs_get_my_threc();
1460 std::vector<uint8_t> message;
1461 cltoma::fuseTruncate::serialize(message, rec->packetId, inode, opened, uid, gid, length);
1462 if (!fs_lizcreatepacket(rec, message)) {
1463 return LIZARDFS_ERROR_IO;
1464 }
1465
1466 try {
1467 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_TRUNCATE, message)) {
1468 return LIZARDFS_ERROR_IO;
1469 }
1470
1471 clientPerforms = false;
1472 uint32_t messageId;
1473 PacketVersion packetVersion;
1474 deserializePacketVersionNoHeader(message, packetVersion);
1475 if (packetVersion == matocl::fuseTruncate::kStatusPacketVersion) {
1476 uint8_t status;
1477 matocl::fuseTruncate::deserialize(message, messageId, status);
1478 if (status == LIZARDFS_STATUS_OK) {
1479 lzfs_pretty_syslog (LOG_NOTICE,
1480 "Received LIZARDFS_STATUS_OK in message LIZ_MATOCL_FUSE_TRUNCATE with version"
1481 " %d" PRIu32, matocl::fuseTruncate::kStatusPacketVersion);
1482 setDisconnect(true);
1483 return LIZARDFS_ERROR_IO;
1484 }
1485 return status;
1486 } else if (packetVersion == matocl::fuseTruncate::kFinishedPacketVersion) {
1487 matocl::fuseTruncate::deserialize(message, messageId, attr);
1488 } else if (packetVersion == matocl::fuseTruncate::kInProgressPacketVersion) {
1489 clientPerforms = true;
1490 matocl::fuseTruncate::deserialize(message, messageId, oldLength, lockId);
1491 } else {
1492 lzfs_pretty_syslog(LOG_NOTICE, "LIZ_MATOCL_FUSE_TRUNCATE - wrong packet version");
1493 setDisconnect(true);
1494 return LIZARDFS_ERROR_IO;
1495 }
1496 } catch (IncorrectDeserializationException& ex) {
1497 lzfs_pretty_syslog(LOG_NOTICE,
1498 "got inconsistent LIZ_MATOCL_FUSE_TRUNCATE message from master "
1499 "(length:%" PRIu64"), %s", message.size(), ex.what());
1500 setDisconnect(true);
1501 return LIZARDFS_ERROR_IO;
1502 }
1503
1504 return LIZARDFS_STATUS_OK;
1505 }
1506
fs_truncateend(uint32_t inode,uint32_t uid,uint32_t gid,uint64_t length,uint32_t lockId,Attributes & attr)1507 uint8_t fs_truncateend(uint32_t inode, uint32_t uid, uint32_t gid, uint64_t length, uint32_t lockId,
1508 Attributes& attr) {
1509 threc *rec = fs_get_my_threc();
1510 std::vector<uint8_t> message;
1511 cltoma::fuseTruncateEnd::serialize(message, rec->packetId, inode, uid, gid, length, lockId);
1512 if (!fs_lizcreatepacket(rec, message)) {
1513 return LIZARDFS_ERROR_IO;
1514 }
1515
1516 try {
1517 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_TRUNCATE_END, message)) {
1518 return LIZARDFS_ERROR_IO;
1519 }
1520
1521 PacketVersion packetVersion;
1522 deserializePacketVersionNoHeader(message, packetVersion);
1523 uint32_t messageId;
1524 if (packetVersion == matocl::fuseTruncateEnd::kStatusPacketVersion) {
1525 uint8_t status;
1526 matocl::fuseTruncateEnd::deserialize(message, messageId, status);
1527 if (status == LIZARDFS_STATUS_OK) {
1528 lzfs_pretty_syslog (LOG_NOTICE,
1529 "Received LIZARDFS_STATUS_OK in message LIZ_MATOCL_FUSE_TRUNCATE_END with version"
1530 " %d" PRIu32, matocl::fuseTruncateEnd::kStatusPacketVersion);
1531 setDisconnect(true);
1532 return LIZARDFS_ERROR_IO;
1533 }
1534 return status;
1535 } else if (packetVersion == matocl::fuseTruncateEnd::kResponsePacketVersion) {
1536 matocl::fuseTruncateEnd::deserialize(message, messageId, attr);
1537 } else {
1538 lzfs_pretty_syslog(LOG_NOTICE, "LIZ_MATOCL_FUSE_TRUNCATE_END - wrong packet version");
1539 setDisconnect(true);
1540 return LIZARDFS_ERROR_IO;
1541 }
1542 } catch (IncorrectDeserializationException& ex) {
1543 lzfs_pretty_syslog(LOG_NOTICE,
1544 "got inconsistent LIZ_MATOCL_FUSE_TRUNCATE_END message from master "
1545 "(length:%" PRIu64"), %s", message.size(), ex.what());
1546 setDisconnect(true);
1547 return LIZARDFS_ERROR_IO;
1548 }
1549
1550 return LIZARDFS_STATUS_OK;
1551 }
1552
1553
fs_readlink(uint32_t inode,const uint8_t ** path)1554 uint8_t fs_readlink(uint32_t inode,const uint8_t **path) {
1555 uint8_t *wptr;
1556 const uint8_t *rptr;
1557 uint32_t i;
1558 uint32_t pleng;
1559 uint8_t ret;
1560 threc *rec = fs_get_my_threc();
1561 wptr = fs_createpacket(rec,CLTOMA_FUSE_READLINK,4);
1562 if (wptr==NULL) {
1563 return LIZARDFS_ERROR_IO;
1564 }
1565 put32bit(&wptr,inode);
1566 rptr = fs_sendandreceive(rec,MATOCL_FUSE_READLINK,&i);
1567 if (rptr==NULL) {
1568 ret = LIZARDFS_ERROR_IO;
1569 } else if (i==1) {
1570 ret = rptr[0];
1571 } else if (i<4) {
1572 setDisconnect(true);
1573 ret = LIZARDFS_ERROR_IO;
1574 } else {
1575 pleng = get32bit(&rptr);
1576 if (i!=4+pleng || pleng==0 || rptr[pleng-1]!=0) {
1577 setDisconnect(true);
1578 ret = LIZARDFS_ERROR_IO;
1579 } else {
1580 *path = rptr;
1581 ret = LIZARDFS_STATUS_OK;
1582 }
1583 }
1584 return ret;
1585 }
1586
fs_symlink(uint32_t parent,uint8_t nleng,const uint8_t * name,const uint8_t * path,uint32_t uid,uint32_t gid,uint32_t * inode,Attributes & attr)1587 uint8_t fs_symlink(uint32_t parent, uint8_t nleng, const uint8_t *name, const uint8_t *path, uint32_t uid, uint32_t gid, uint32_t *inode, Attributes &attr) {
1588 uint8_t *wptr;
1589 const uint8_t *rptr;
1590 uint32_t i;
1591 uint32_t t32;
1592 uint8_t ret;
1593 threc *rec = fs_get_my_threc();
1594 t32 = strlen((const char *)path)+1;
1595 wptr = fs_createpacket(rec,CLTOMA_FUSE_SYMLINK,t32+nleng+17);
1596 if (wptr==NULL) {
1597 return LIZARDFS_ERROR_IO;
1598 }
1599 put32bit(&wptr,parent);
1600 put8bit(&wptr,nleng);
1601 memcpy(wptr,name,nleng);
1602 wptr+=nleng;
1603 put32bit(&wptr,t32);
1604 memcpy(wptr,path,t32);
1605 wptr+=t32;
1606 put32bit(&wptr,uid);
1607 put32bit(&wptr,gid);
1608 rptr = fs_sendandreceive(rec,MATOCL_FUSE_SYMLINK,&i);
1609 if (rptr==NULL) {
1610 ret = LIZARDFS_ERROR_IO;
1611 } else if (i==1) {
1612 ret = rptr[0];
1613 } else if (i != (attr.size() + 4)) {
1614 setDisconnect(true);
1615 ret = LIZARDFS_ERROR_IO;
1616 } else {
1617 t32 = get32bit(&rptr);
1618 *inode = t32;
1619 memcpy(attr.data(), rptr, attr.size());
1620 ret = LIZARDFS_STATUS_OK;
1621 }
1622 return ret;
1623 }
1624
fs_mknod(uint32_t parent,uint8_t nleng,const uint8_t * name,uint8_t type,uint16_t mode,uint16_t umask,uint32_t uid,uint32_t gid,uint32_t rdev,uint32_t & inode,Attributes & attr)1625 uint8_t fs_mknod(uint32_t parent, uint8_t nleng, const uint8_t *name, uint8_t type,
1626 uint16_t mode, uint16_t umask, uint32_t uid, uint32_t gid, uint32_t rdev,
1627 uint32_t &inode, Attributes& attr) {
1628 threc* rec = fs_get_my_threc();
1629 auto message = cltoma::fuseMknod::build(rec->packetId, parent,
1630 MooseFsString<uint8_t>(reinterpret_cast<const char*>(name), nleng),
1631 type, mode, umask, uid, gid, rdev);
1632 if (!fs_lizcreatepacket(rec, message)) {
1633 return LIZARDFS_ERROR_IO;
1634 }
1635 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_MKNOD, message)) {
1636 return LIZARDFS_ERROR_IO;
1637 }
1638 try {
1639 uint32_t messageId;
1640 PacketVersion packetVersion;
1641 deserializePacketVersionNoHeader(message, packetVersion);
1642 if (packetVersion == matocl::fuseMkdir::kStatusPacketVersion) {
1643 uint8_t status;
1644 matocl::fuseMknod::deserialize(message, messageId, status);
1645 if (status == LIZARDFS_STATUS_OK) {
1646 fs_got_inconsistent("LIZ_MATOCL_FUSE_MKNOD", message.size(),
1647 "version 0 and LIZARDFS_STATUS_OK");
1648 return LIZARDFS_ERROR_IO;
1649 }
1650 return status;
1651 } else if (packetVersion == matocl::fuseMkdir::kResponsePacketVersion) {
1652 matocl::fuseMknod::deserialize(message, messageId, inode, attr);
1653 return LIZARDFS_STATUS_OK;
1654 } else {
1655 fs_got_inconsistent("LIZ_MATOCL_FUSE_MKNOD", message.size(),
1656 "unknown version " + std::to_string(packetVersion));
1657 return LIZARDFS_ERROR_IO;
1658 }
1659 return LIZARDFS_ERROR_ENOTSUP;
1660 } catch (Exception& ex) {
1661 fs_got_inconsistent("LIZ_MATOCL_FUSE_MKNOD", message.size(), ex.what());
1662 return LIZARDFS_ERROR_IO;
1663 }
1664 }
1665
fs_mkdir(uint32_t parent,uint8_t nleng,const uint8_t * name,uint16_t mode,uint16_t umask,uint32_t uid,uint32_t gid,uint8_t copysgid,uint32_t & inode,Attributes & attr)1666 uint8_t fs_mkdir(uint32_t parent, uint8_t nleng, const uint8_t *name,
1667 uint16_t mode, uint16_t umask, uint32_t uid, uint32_t gid,
1668 uint8_t copysgid,uint32_t &inode, Attributes& attr) {
1669 threc* rec = fs_get_my_threc();
1670 auto message = cltoma::fuseMkdir::build(rec->packetId, parent,
1671 MooseFsString<uint8_t>(reinterpret_cast<const char*>(name), nleng),
1672 mode, umask, uid, gid, copysgid);
1673 if (!fs_lizcreatepacket(rec, message)) {
1674 return LIZARDFS_ERROR_IO;
1675 }
1676 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_MKDIR, message)) {
1677 return LIZARDFS_ERROR_IO;
1678 }
1679 try {
1680 uint32_t messageId;
1681 PacketVersion packetVersion;
1682 deserializePacketVersionNoHeader(message, packetVersion);
1683 if (packetVersion == matocl::fuseMkdir::kStatusPacketVersion) {
1684 uint8_t status;
1685 matocl::fuseMkdir::deserialize(message, messageId, status);
1686 if (status == LIZARDFS_STATUS_OK) {
1687 fs_got_inconsistent("LIZ_MATOCL_FUSE_MKDIR", message.size(),
1688 "version 0 and LIZARDFS_STATUS_OK");
1689 return LIZARDFS_ERROR_IO;
1690 }
1691 return status;
1692 } else if (packetVersion == matocl::fuseMkdir::kResponsePacketVersion) {
1693 matocl::fuseMkdir::deserialize(message, messageId, inode, attr);
1694 return LIZARDFS_STATUS_OK;
1695 } else {
1696 fs_got_inconsistent("LIZ_MATOCL_FUSE_MKDIR", message.size(),
1697 "unknown version " + std::to_string(packetVersion));
1698 return LIZARDFS_ERROR_IO;
1699 }
1700 return LIZARDFS_ERROR_ENOTSUP;
1701 } catch (Exception& ex) {
1702 fs_got_inconsistent("LIZ_MATOCL_FUSE_MKDIR", message.size(), ex.what());
1703 return LIZARDFS_ERROR_IO;
1704 }
1705 }
1706
fs_unlink(uint32_t parent,uint8_t nleng,const uint8_t * name,uint32_t uid,uint32_t gid)1707 uint8_t fs_unlink(uint32_t parent,uint8_t nleng,const uint8_t *name,uint32_t uid,uint32_t gid) {
1708 uint8_t *wptr;
1709 const uint8_t *rptr;
1710 uint32_t i;
1711 uint8_t ret;
1712 threc *rec = fs_get_my_threc();
1713 wptr = fs_createpacket(rec,CLTOMA_FUSE_UNLINK,13+nleng);
1714 if (wptr==NULL) {
1715 return LIZARDFS_ERROR_IO;
1716 }
1717 put32bit(&wptr,parent);
1718 put8bit(&wptr,nleng);
1719 memcpy(wptr,name,nleng);
1720 wptr+=nleng;
1721 put32bit(&wptr,uid);
1722 put32bit(&wptr,gid);
1723 rptr = fs_sendandreceive(rec,MATOCL_FUSE_UNLINK,&i);
1724 if (rptr==NULL) {
1725 ret = LIZARDFS_ERROR_IO;
1726 } else if (i==1) {
1727 ret = rptr[0];
1728 } else {
1729 setDisconnect(true);
1730 ret = LIZARDFS_ERROR_IO;
1731 }
1732 return ret;
1733 }
1734
fs_rmdir(uint32_t parent,uint8_t nleng,const uint8_t * name,uint32_t uid,uint32_t gid)1735 uint8_t fs_rmdir(uint32_t parent,uint8_t nleng,const uint8_t *name,uint32_t uid,uint32_t gid) {
1736 uint8_t *wptr;
1737 const uint8_t *rptr;
1738 uint32_t i;
1739 uint8_t ret;
1740 threc *rec = fs_get_my_threc();
1741 wptr = fs_createpacket(rec,CLTOMA_FUSE_RMDIR,13+nleng);
1742 if (wptr==NULL) {
1743 return LIZARDFS_ERROR_IO;
1744 }
1745 put32bit(&wptr,parent);
1746 put8bit(&wptr,nleng);
1747 memcpy(wptr,name,nleng);
1748 wptr+=nleng;
1749 put32bit(&wptr,uid);
1750 put32bit(&wptr,gid);
1751 rptr = fs_sendandreceive(rec,MATOCL_FUSE_RMDIR,&i);
1752 if (rptr==NULL) {
1753 ret = LIZARDFS_ERROR_IO;
1754 } else if (i==1) {
1755 ret = rptr[0];
1756 } else {
1757 setDisconnect(true);
1758 ret = LIZARDFS_ERROR_IO;
1759 }
1760 return ret;
1761 }
1762
fs_rename(uint32_t parent_src,uint8_t nleng_src,const uint8_t * name_src,uint32_t parent_dst,uint8_t nleng_dst,const uint8_t * name_dst,uint32_t uid,uint32_t gid,uint32_t * inode,Attributes & attr)1763 uint8_t fs_rename(uint32_t parent_src, uint8_t nleng_src, const uint8_t *name_src, uint32_t parent_dst, uint8_t nleng_dst, const uint8_t *name_dst, uint32_t uid, uint32_t gid, uint32_t *inode, Attributes &attr) {
1764 uint8_t *wptr;
1765 const uint8_t *rptr;
1766 uint32_t i;
1767 uint32_t t32;
1768 uint8_t ret;
1769 threc *rec = fs_get_my_threc();
1770 wptr = fs_createpacket(rec,CLTOMA_FUSE_RENAME,18+nleng_src+nleng_dst);
1771 if (wptr==NULL) {
1772 return LIZARDFS_ERROR_IO;
1773 }
1774 put32bit(&wptr,parent_src);
1775 put8bit(&wptr,nleng_src);
1776 memcpy(wptr,name_src,nleng_src);
1777 wptr+=nleng_src;
1778 put32bit(&wptr,parent_dst);
1779 put8bit(&wptr,nleng_dst);
1780 memcpy(wptr,name_dst,nleng_dst);
1781 wptr+=nleng_dst;
1782 put32bit(&wptr,uid);
1783 put32bit(&wptr,gid);
1784 rptr = fs_sendandreceive(rec,MATOCL_FUSE_RENAME,&i);
1785 if (rptr==NULL) {
1786 ret = LIZARDFS_ERROR_IO;
1787 } else if (i==1) {
1788 ret = rptr[0];
1789 *inode = 0;
1790 attr.fill(0);
1791 } else if (i != (attr.size() + 4)) {
1792 setDisconnect(true);
1793 ret = LIZARDFS_ERROR_IO;
1794 } else {
1795 t32 = get32bit(&rptr);
1796 *inode = t32;
1797 memcpy(attr.data(), rptr, attr.size());
1798 ret = LIZARDFS_STATUS_OK;
1799 }
1800 return ret;
1801 }
1802
fs_link(uint32_t inode_src,uint32_t parent_dst,uint8_t nleng_dst,const uint8_t * name_dst,uint32_t uid,uint32_t gid,uint32_t * inode,Attributes & attr)1803 uint8_t fs_link(uint32_t inode_src, uint32_t parent_dst, uint8_t nleng_dst, const uint8_t *name_dst, uint32_t uid, uint32_t gid, uint32_t *inode, Attributes &attr) {
1804 uint8_t *wptr;
1805 const uint8_t *rptr;
1806 uint32_t i;
1807 uint32_t t32;
1808 uint8_t ret;
1809 threc *rec = fs_get_my_threc();
1810 wptr = fs_createpacket(rec,CLTOMA_FUSE_LINK,17+nleng_dst);
1811 if (wptr==NULL) {
1812 return LIZARDFS_ERROR_IO;
1813 }
1814 put32bit(&wptr,inode_src);
1815 put32bit(&wptr,parent_dst);
1816 put8bit(&wptr,nleng_dst);
1817 memcpy(wptr,name_dst,nleng_dst);
1818 wptr+=nleng_dst;
1819 put32bit(&wptr,uid);
1820 put32bit(&wptr,gid);
1821 rptr = fs_sendandreceive(rec,MATOCL_FUSE_LINK,&i);
1822 if (rptr==NULL) {
1823 ret = LIZARDFS_ERROR_IO;
1824 } else if (i==1) {
1825 ret = rptr[0];
1826 } else if (i != (attr.size() + 4)) {
1827 setDisconnect(true);
1828 ret = LIZARDFS_ERROR_IO;
1829 } else {
1830 t32 = get32bit(&rptr);
1831 *inode = t32;
1832 memcpy(attr.data(), rptr, attr.size());
1833 ret = LIZARDFS_STATUS_OK;
1834 }
1835 return ret;
1836 }
1837
fs_getdir(uint32_t inode,uint32_t uid,uint32_t gid,const uint8_t ** dbuff,uint32_t * dbuffsize)1838 uint8_t fs_getdir(uint32_t inode,uint32_t uid,uint32_t gid,const uint8_t **dbuff,uint32_t *dbuffsize) {
1839 uint8_t *wptr;
1840 const uint8_t *rptr;
1841 uint32_t i;
1842 uint8_t ret;
1843 threc *rec = fs_get_my_threc();
1844 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETDIR,12);
1845 if (wptr==NULL) {
1846 return LIZARDFS_ERROR_IO;
1847 }
1848 put32bit(&wptr,inode);
1849 put32bit(&wptr,uid);
1850 put32bit(&wptr,gid);
1851 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETDIR,&i);
1852 if (rptr==NULL) {
1853 ret = LIZARDFS_ERROR_IO;
1854 } else if (i==1) {
1855 ret = rptr[0];
1856 } else {
1857 *dbuff = rptr;
1858 *dbuffsize = i;
1859 ret = LIZARDFS_STATUS_OK;
1860 }
1861 return ret;
1862 }
1863
fs_getdir_plus(uint32_t inode,uint32_t uid,uint32_t gid,uint8_t addtocache,const uint8_t ** dbuff,uint32_t * dbuffsize)1864 uint8_t fs_getdir_plus(uint32_t inode,uint32_t uid,uint32_t gid,uint8_t addtocache,const uint8_t **dbuff,uint32_t *dbuffsize) {
1865 uint8_t *wptr;
1866 const uint8_t *rptr;
1867 uint32_t i;
1868 uint8_t ret;
1869 uint8_t flags;
1870 threc *rec = fs_get_my_threc();
1871 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETDIR,13);
1872 if (wptr==NULL) {
1873 return LIZARDFS_ERROR_IO;
1874 }
1875 put32bit(&wptr,inode);
1876 put32bit(&wptr,uid);
1877 put32bit(&wptr,gid);
1878 flags = GETDIR_FLAG_WITHATTR;
1879 if (addtocache) {
1880 flags |= GETDIR_FLAG_ADDTOCACHE;
1881 }
1882 put8bit(&wptr,flags);
1883 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETDIR,&i);
1884 if (rptr==NULL) {
1885 ret = LIZARDFS_ERROR_IO;
1886 } else if (i==1) {
1887 ret = rptr[0];
1888 } else {
1889 *dbuff = rptr;
1890 *dbuffsize = i;
1891 ret = LIZARDFS_STATUS_OK;
1892 }
1893 return ret;
1894 }
1895
fs_getdir(uint32_t inode,uint32_t uid,uint32_t gid,uint64_t first_entry,uint64_t max_entries,std::vector<DirectoryEntry> & dir_entries)1896 uint8_t fs_getdir(uint32_t inode, uint32_t uid, uint32_t gid, uint64_t first_entry,
1897 uint64_t max_entries, std::vector<DirectoryEntry> &dir_entries) {
1898 threc *rec = fs_get_my_threc();
1899 auto message =
1900 cltoma::fuseGetDir::build(rec->packetId, inode, uid, gid, first_entry, max_entries);
1901 if (!fs_lizcreatepacket(rec, message)) {
1902 return LIZARDFS_ERROR_IO;
1903 }
1904 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_GETDIR, message)) {
1905 return LIZARDFS_ERROR_IO;
1906 }
1907 try {
1908 uint32_t message_id;
1909 PacketVersion packet_version;
1910 deserializePacketVersionNoHeader(message, packet_version);
1911 if (packet_version == matocl::fuseGetDir::kStatus) {
1912 uint8_t status;
1913 matocl::fuseGetDir::deserialize(message, message_id, status);
1914 if (status == LIZARDFS_STATUS_OK) {
1915 fs_got_inconsistent("LIZ_MATOCL_FUSE_GETDIR", message.size(),
1916 "version 0 and LIZARDFS_STATUS_OK");
1917 return LIZARDFS_ERROR_IO;
1918 }
1919 return status;
1920 } else if (packet_version == matocl::fuseGetDir::kResponse) {
1921 matocl::fuseGetDir::deserialize(message, message_id, first_entry,
1922 dir_entries);
1923 return LIZARDFS_STATUS_OK;
1924 } else {
1925 fs_got_inconsistent("LIZ_MATOCL_FUSE_GETDIR", message.size(),
1926 "unknown version " + std::to_string(packet_version));
1927 return LIZARDFS_ERROR_IO;
1928 }
1929 } catch (Exception &ex) {
1930 fs_got_inconsistent("LIZ_MATOCL_FUSE_GETDIR", message.size(), ex.what());
1931 return LIZARDFS_ERROR_IO;
1932 }
1933 }
1934
1935 // FUSE - I/O
1936
fs_opencheck(uint32_t inode,uint32_t uid,uint32_t gid,uint8_t flags,Attributes & attr)1937 uint8_t fs_opencheck(uint32_t inode, uint32_t uid, uint32_t gid, uint8_t flags, Attributes &attr) {
1938 uint8_t *wptr;
1939 const uint8_t *rptr;
1940 uint32_t i;
1941 uint8_t ret;
1942 threc *rec = fs_get_my_threc();
1943 wptr = fs_createpacket(rec,CLTOMA_FUSE_OPEN,13);
1944 if (wptr==NULL) {
1945 return LIZARDFS_ERROR_IO;
1946 }
1947 put32bit(&wptr,inode);
1948 put32bit(&wptr,uid);
1949 put32bit(&wptr,gid);
1950 put8bit(&wptr,flags);
1951 fs_inc_acnt(inode);
1952 rptr = fs_sendandreceive(rec,MATOCL_FUSE_OPEN,&i);
1953 if (rptr==NULL) {
1954 ret = LIZARDFS_ERROR_IO;
1955 } else if (i==1) {
1956 attr.fill(0);
1957 ret = rptr[0];
1958 } else if (i == attr.size()) {
1959 memcpy(attr.data(), rptr, attr.size());
1960 ret = LIZARDFS_STATUS_OK;
1961 } else {
1962 setDisconnect(true);
1963 ret = LIZARDFS_ERROR_IO;
1964 }
1965 if (ret) { // release on error
1966 fs_dec_acnt(inode);
1967 }
1968 return ret;
1969 }
1970
fs_update_credentials(uint32_t key,const GroupCache::Groups & gids)1971 uint8_t fs_update_credentials(uint32_t key, const GroupCache::Groups &gids) {
1972 threc* rec = fs_get_my_threc();
1973 std::vector<uint8_t> message;
1974 cltoma::updateCredentials::serialize(message, rec->packetId, key, gids);
1975 if (!fs_lizcreatepacket(rec, message)) {
1976 return LIZARDFS_ERROR_IO;
1977 }
1978 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_UPDATE_CREDENTIALS, message)) {
1979 return LIZARDFS_ERROR_IO;
1980 }
1981 try {
1982 uint8_t status;
1983 uint32_t msgid;
1984 matocl::updateCredentials::deserialize(message, msgid, status);
1985 return status;
1986 } catch (Exception& ex) {
1987 setDisconnect(true);
1988 return LIZARDFS_ERROR_IO;
1989 }
1990 }
1991
fs_release(uint32_t inode)1992 void fs_release(uint32_t inode) {
1993 fs_dec_acnt(inode);
1994 }
1995
fs_readchunk(uint32_t inode,uint32_t indx,uint64_t * length,uint64_t * chunkid,uint32_t * version,const uint8_t ** csdata,uint32_t * csdatasize)1996 uint8_t fs_readchunk(uint32_t inode,uint32_t indx,uint64_t *length,uint64_t *chunkid,uint32_t *version,const uint8_t **csdata,uint32_t *csdatasize) {
1997 uint8_t *wptr;
1998 const uint8_t *rptr;
1999 uint32_t i;
2000 uint8_t ret;
2001 uint64_t t64;
2002 uint32_t t32;
2003 threc *rec = fs_get_my_threc();
2004 *csdata=NULL;
2005 *csdatasize=0;
2006 wptr = fs_createpacket(rec,CLTOMA_FUSE_READ_CHUNK,8);
2007 if (wptr==NULL) {
2008 return LIZARDFS_ERROR_IO;
2009 }
2010
2011 put32bit(&wptr,inode);
2012 put32bit(&wptr,indx);
2013 rptr = fs_sendandreceive(rec,MATOCL_FUSE_READ_CHUNK,&i);
2014 if (rptr==NULL) {
2015 ret = LIZARDFS_ERROR_IO;
2016 } else if (i==1) {
2017 ret = rptr[0];
2018 } else if (i<20 || ((i-20)%6)!=0) {
2019 setDisconnect(true);
2020 ret = LIZARDFS_ERROR_IO;
2021 } else {
2022 t64 = get64bit(&rptr);
2023 *length = t64;
2024 t64 = get64bit(&rptr);
2025 *chunkid = t64;
2026 t32 = get32bit(&rptr);
2027 *version = t32;
2028 if (i>20) {
2029 *csdata = rptr;
2030 *csdatasize = i-20;
2031 }
2032 ret = LIZARDFS_STATUS_OK;
2033 }
2034 return ret;
2035 }
2036
fs_lizreadchunk(std::vector<ChunkTypeWithAddress> & chunkservers,uint64_t & chunkId,uint32_t & chunkVersion,uint64_t & fileLength,uint32_t inode,uint32_t chunkIndex)2037 uint8_t fs_lizreadchunk(std::vector<ChunkTypeWithAddress> &chunkservers, uint64_t &chunkId,
2038 uint32_t &chunkVersion, uint64_t &fileLength, uint32_t inode, uint32_t chunkIndex) {
2039 threc *rec = fs_get_my_threc();
2040
2041 std::vector<uint8_t> message;
2042 cltoma::fuseReadChunk::serialize(message, rec->packetId, inode, chunkIndex);
2043 if (!fs_lizcreatepacket(rec, message)) {
2044 return LIZARDFS_ERROR_IO;
2045 }
2046
2047 try {
2048 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_READ_CHUNK, message)) {
2049 return LIZARDFS_ERROR_IO;
2050 }
2051 PacketVersion packetVersion;
2052 deserializePacketVersionNoHeader(message, packetVersion);
2053
2054 if (packetVersion == matocl::fuseReadChunk::kStatusPacketVersion) {
2055 uint8_t status;
2056 matocl::fuseReadChunk::deserialize(message, status);
2057 return status;
2058 } else if (packetVersion == matocl::fuseReadChunk::kECChunks_ResponsePacketVersion) {
2059 matocl::fuseReadChunk::deserialize(message, fileLength,
2060 chunkId, chunkVersion, chunkservers);
2061 } else if (packetVersion == matocl::fuseReadChunk::kResponsePacketVersion) {
2062 std::vector<legacy::ChunkTypeWithAddress> legacy_chunkservers;
2063 matocl::fuseReadChunk::deserialize(message, fileLength,
2064 chunkId, chunkVersion, legacy_chunkservers);
2065 chunkservers.clear();
2066 for (const auto &part : legacy_chunkservers) {
2067 chunkservers.push_back(ChunkTypeWithAddress(part.address, ChunkPartType(part.chunkType), kFirstXorVersion));
2068 }
2069 } else {
2070 lzfs_pretty_syslog(LOG_NOTICE, "LIZ_MATOCL_FUSE_READ_CHUNK - wrong packet version");
2071 setDisconnect(true);
2072 return LIZARDFS_ERROR_IO;
2073 }
2074 } catch (IncorrectDeserializationException&) {
2075 setDisconnect(true);
2076 return LIZARDFS_ERROR_IO;
2077 }
2078 return LIZARDFS_STATUS_OK;
2079 }
2080
fs_writechunk(uint32_t inode,uint32_t indx,uint64_t * length,uint64_t * chunkid,uint32_t * version,const uint8_t ** csdata,uint32_t * csdatasize)2081 uint8_t fs_writechunk(uint32_t inode,uint32_t indx,uint64_t *length,uint64_t *chunkid,uint32_t *version,const uint8_t **csdata,uint32_t *csdatasize) {
2082 uint8_t *wptr;
2083 const uint8_t *rptr;
2084 uint32_t i;
2085 uint8_t ret;
2086 uint64_t t64;
2087 uint32_t t32;
2088 threc *rec = fs_get_my_threc();
2089 *csdata=NULL;
2090 *csdatasize=0;
2091 wptr = fs_createpacket(rec,CLTOMA_FUSE_WRITE_CHUNK,8);
2092 if (wptr==NULL) {
2093 return LIZARDFS_ERROR_IO;
2094 }
2095 put32bit(&wptr,inode);
2096 put32bit(&wptr,indx);
2097 rptr = fs_sendandreceive(rec,MATOCL_FUSE_WRITE_CHUNK,&i);
2098 if (rptr==NULL) {
2099 ret = LIZARDFS_ERROR_IO;
2100 } else if (i==1) {
2101 ret = rptr[0];
2102 } else if (i<20 || ((i-20)%6)!=0) {
2103 setDisconnect(true);
2104 ret = LIZARDFS_ERROR_IO;
2105 } else {
2106 t64 = get64bit(&rptr);
2107 *length = t64;
2108 t64 = get64bit(&rptr);
2109 *chunkid = t64;
2110 t32 = get32bit(&rptr);
2111 *version = t32;
2112 if (i>20) {
2113 *csdata = rptr;
2114 *csdatasize = i-20;
2115 }
2116 ret = LIZARDFS_STATUS_OK;
2117 }
2118 return ret;
2119 }
2120
fs_lizwritechunk(uint32_t inode,uint32_t chunkIndex,uint32_t & lockId,uint64_t & fileLength,uint64_t & chunkId,uint32_t & chunkVersion,std::vector<ChunkTypeWithAddress> & chunkservers)2121 uint8_t fs_lizwritechunk(uint32_t inode, uint32_t chunkIndex, uint32_t &lockId,
2122 uint64_t &fileLength, uint64_t &chunkId, uint32_t &chunkVersion,
2123 std::vector<ChunkTypeWithAddress> &chunkservers) {
2124 threc *rec = fs_get_my_threc();
2125
2126 std::vector<uint8_t> message;
2127 cltoma::fuseWriteChunk::serialize(message, rec->packetId, inode, chunkIndex, lockId);
2128 if (!fs_lizcreatepacket(rec, message)) {
2129 return LIZARDFS_ERROR_IO;
2130 }
2131
2132 try {
2133 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_WRITE_CHUNK, message)) {
2134 return LIZARDFS_ERROR_IO;
2135 }
2136
2137 PacketVersion packetVersion;
2138 deserializePacketVersionNoHeader(message, packetVersion);
2139 if (packetVersion == matocl::fuseWriteChunk::kStatusPacketVersion) {
2140 uint8_t status;
2141 matocl::fuseWriteChunk::deserialize(message, status);
2142 if (status == LIZARDFS_STATUS_OK) {
2143 lzfs_pretty_syslog (LOG_NOTICE,
2144 "Received LIZARDFS_STATUS_OK in message LIZ_MATOCL_FUSE_WRITE_CHUNK with version"
2145 " %d" PRIu32, matocl::fuseWriteChunk::kStatusPacketVersion);
2146 setDisconnect(true);
2147 return LIZARDFS_ERROR_IO;
2148 }
2149 return status;
2150 } else if (packetVersion == matocl::fuseWriteChunk::kECChunks_ResponsePacketVersion) {
2151 matocl::fuseWriteChunk::deserialize(message,
2152 fileLength, chunkId, chunkVersion, lockId, chunkservers);
2153 } else if (packetVersion == matocl::fuseWriteChunk::kResponsePacketVersion) {
2154 std::vector<legacy::ChunkTypeWithAddress> legacy_chunkservers;
2155 matocl::fuseWriteChunk::deserialize(message,
2156 fileLength, chunkId, chunkVersion, lockId, legacy_chunkservers);
2157 chunkservers.clear();
2158 for (const auto &part : legacy_chunkservers) {
2159 chunkservers.push_back(ChunkTypeWithAddress(part.address, ChunkPartType(part.chunkType), kFirstXorVersion));
2160 }
2161 } else {
2162 lzfs_pretty_syslog(LOG_NOTICE, "LIZ_MATOCL_FUSE_WRITE_CHUNK - wrong packet version");
2163 setDisconnect(true);
2164 return LIZARDFS_ERROR_IO;
2165 }
2166 } catch (IncorrectDeserializationException& ex) {
2167 lzfs_pretty_syslog(LOG_NOTICE,
2168 "got inconsistent LIZ_MATOCL_FUSE_WRITE_CHUNK message from master "
2169 "(length:%" PRIu64"), %s", message.size(), ex.what());
2170 setDisconnect(true);
2171 return LIZARDFS_ERROR_IO;
2172 }
2173
2174 return LIZARDFS_STATUS_OK;
2175 }
2176
fs_lizwriteend(uint64_t chunkId,uint32_t lockId,uint32_t inode,uint64_t length)2177 uint8_t fs_lizwriteend(uint64_t chunkId, uint32_t lockId, uint32_t inode, uint64_t length) {
2178 threc* rec = fs_get_my_threc();
2179 std::vector<uint8_t> message;
2180 cltoma::fuseWriteChunkEnd::serialize(message, rec->packetId, chunkId, lockId, inode, length);
2181 if (!fs_lizcreatepacket(rec, message)) {
2182 return LIZARDFS_ERROR_IO;
2183 }
2184 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_WRITE_CHUNK_END, message)) {
2185 return LIZARDFS_ERROR_IO;
2186 }
2187 try {
2188 uint8_t status;
2189 matocl::fuseWriteChunkEnd::deserialize(message, status);
2190 return status;
2191 } catch (Exception& ex) {
2192 lzfs_pretty_syslog(LOG_NOTICE,
2193 "got inconsistent LIZ_MATOCL_FUSE_WRITE_CHUNK_END message from master "
2194 "(length:%" PRIu64"), %s", message.size(), ex.what());
2195 setDisconnect(true);
2196 return LIZARDFS_ERROR_IO;
2197 }
2198 }
2199
fs_writeend(uint64_t chunkid,uint32_t inode,uint64_t length)2200 uint8_t fs_writeend(uint64_t chunkid, uint32_t inode, uint64_t length) {
2201 uint8_t *wptr;
2202 const uint8_t *rptr;
2203 uint32_t i;
2204 uint8_t ret;
2205 threc *rec = fs_get_my_threc();
2206 wptr = fs_createpacket(rec,CLTOMA_FUSE_WRITE_CHUNK_END,20);
2207 if (wptr==NULL) {
2208 return LIZARDFS_ERROR_IO;
2209 }
2210 put64bit(&wptr,chunkid);
2211 put32bit(&wptr,inode);
2212 put64bit(&wptr,length);
2213 rptr = fs_sendandreceive(rec,MATOCL_FUSE_WRITE_CHUNK_END,&i);
2214 if (rptr==NULL) {
2215 ret = LIZARDFS_ERROR_IO;
2216 } else if (i==1) {
2217 ret = rptr[0];
2218 } else {
2219 setDisconnect(true);
2220 ret = LIZARDFS_ERROR_IO;
2221 }
2222 return ret;
2223 }
2224
2225
2226 // FUSE - META
2227
2228
fs_getreserved(const uint8_t ** dbuff,uint32_t * dbuffsize)2229 uint8_t fs_getreserved(const uint8_t **dbuff,uint32_t *dbuffsize) {
2230 uint8_t *wptr;
2231 const uint8_t *rptr;
2232 uint32_t i;
2233 uint8_t ret;
2234 threc *rec = fs_get_my_threc();
2235 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETRESERVED,0);
2236 if (wptr==NULL) {
2237 return LIZARDFS_ERROR_IO;
2238 }
2239 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETRESERVED,&i);
2240 if (rptr==NULL) {
2241 ret = LIZARDFS_ERROR_IO;
2242 } else if (i==1) {
2243 ret = rptr[0];
2244 } else {
2245 *dbuff = rptr;
2246 *dbuffsize = i;
2247 ret = LIZARDFS_STATUS_OK;
2248 }
2249 return ret;
2250 }
2251
fs_gettrash(const uint8_t ** dbuff,uint32_t * dbuffsize)2252 uint8_t fs_gettrash(const uint8_t **dbuff,uint32_t *dbuffsize) {
2253 uint8_t *wptr;
2254 const uint8_t *rptr;
2255 uint32_t i;
2256 uint8_t ret;
2257 threc *rec = fs_get_my_threc();
2258 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETTRASH,0);
2259 if (wptr==NULL) {
2260 return LIZARDFS_ERROR_IO;
2261 }
2262 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETTRASH,&i);
2263 if (rptr==NULL) {
2264 ret = LIZARDFS_ERROR_IO;
2265 } else if (i==1) {
2266 ret = rptr[0];
2267 } else {
2268 *dbuff = rptr;
2269 *dbuffsize = i;
2270 ret = LIZARDFS_STATUS_OK;
2271 }
2272 return ret;
2273 }
2274
fs_getreserved(LizardClient::NamedInodeOffset off,LizardClient::NamedInodeOffset max_entries,std::vector<NamedInodeEntry> & entries)2275 uint8_t fs_getreserved(LizardClient::NamedInodeOffset off, LizardClient::NamedInodeOffset max_entries,
2276 std::vector<NamedInodeEntry> &entries) {
2277 threc *rec = fs_get_my_threc();
2278 auto message = cltoma::fuseGetReserved::build(rec->packetId, off, max_entries);
2279 if (!fs_lizcreatepacket(rec, message)) {
2280 return LIZARDFS_ERROR_IO;
2281 }
2282 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_GETRESERVED, message)) {
2283 return LIZARDFS_ERROR_IO;
2284 }
2285 try {
2286 PacketVersion dummy_packet_version;
2287 uint32_t dummy_message_id;
2288 deserializePacketVersionNoHeader(message, dummy_packet_version);
2289 matocl::fuseGetReserved::deserialize(message, dummy_message_id, entries);
2290 return LIZARDFS_STATUS_OK;
2291 } catch (Exception &ex) {
2292 fs_got_inconsistent("LIZ_MATOCL_FUSE_GETRESERVED", message.size(), ex.what());
2293 return LIZARDFS_ERROR_IO;
2294 }
2295 }
2296
fs_gettrash(LizardClient::NamedInodeOffset off,LizardClient::NamedInodeOffset max_entries,std::vector<NamedInodeEntry> & entries)2297 uint8_t fs_gettrash(LizardClient::NamedInodeOffset off, LizardClient::NamedInodeOffset max_entries,
2298 std::vector<NamedInodeEntry> &entries) {
2299 threc *rec = fs_get_my_threc();
2300 auto message = cltoma::fuseGetTrash::build(rec->packetId, off, max_entries);
2301 if (!fs_lizcreatepacket(rec, message)) {
2302 return LIZARDFS_ERROR_IO;
2303 }
2304 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_GETTRASH, message)) {
2305 return LIZARDFS_ERROR_IO;
2306 }
2307 try {
2308 PacketVersion dummy_packet_version;
2309 uint32_t dummy_message_id;
2310 deserializePacketVersionNoHeader(message, dummy_packet_version);
2311 matocl::fuseGetTrash::deserialize(message, dummy_message_id, entries);
2312 return LIZARDFS_STATUS_OK;
2313 } catch (Exception &ex) {
2314 fs_got_inconsistent("LIZ_MATOCL_FUSE_GETTRASH", message.size(), ex.what());
2315 return LIZARDFS_ERROR_IO;
2316 }
2317 }
2318
fs_getdetachedattr(uint32_t inode,Attributes & attr)2319 uint8_t fs_getdetachedattr(uint32_t inode, Attributes &attr) {
2320 uint8_t *wptr;
2321 const uint8_t *rptr;
2322 uint32_t i;
2323 uint8_t ret;
2324 threc *rec = fs_get_my_threc();
2325 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETDETACHEDATTR,4);
2326 if (wptr==NULL) {
2327 return LIZARDFS_ERROR_IO;
2328 }
2329 put32bit(&wptr,inode);
2330 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETDETACHEDATTR,&i);
2331 if (rptr==NULL) {
2332 ret = LIZARDFS_ERROR_IO;
2333 } else if (i==1) {
2334 ret = rptr[0];
2335 } else if (i != attr.size()) {
2336 setDisconnect(true);
2337 ret = LIZARDFS_ERROR_IO;
2338 } else {
2339 memcpy(attr.data(), rptr, attr.size());
2340 ret = LIZARDFS_STATUS_OK;
2341 }
2342 return ret;
2343 }
2344
fs_gettrashpath(uint32_t inode,const uint8_t ** path)2345 uint8_t fs_gettrashpath(uint32_t inode,const uint8_t **path) {
2346 uint8_t *wptr;
2347 const uint8_t *rptr;
2348 uint32_t i;
2349 uint32_t pleng;
2350 uint8_t ret;
2351 threc *rec = fs_get_my_threc();
2352 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETTRASHPATH,4);
2353 if (wptr==NULL) {
2354 return LIZARDFS_ERROR_IO;
2355 }
2356 put32bit(&wptr,inode);
2357 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETTRASHPATH,&i);
2358 if (rptr==NULL) {
2359 ret = LIZARDFS_ERROR_IO;
2360 } else if (i==1) {
2361 ret = rptr[0];
2362 } else if (i<4) {
2363 setDisconnect(true);
2364 ret = LIZARDFS_ERROR_IO;
2365 } else {
2366 pleng = get32bit(&rptr);
2367 if (i!=4+pleng || pleng==0 || rptr[pleng-1]!=0) {
2368 setDisconnect(true);
2369 ret = LIZARDFS_ERROR_IO;
2370 } else {
2371 *path = rptr;
2372 ret = LIZARDFS_STATUS_OK;
2373 }
2374 }
2375 return ret;
2376 }
2377
fs_settrashpath(uint32_t inode,const uint8_t * path)2378 uint8_t fs_settrashpath(uint32_t inode,const uint8_t *path) {
2379 uint8_t *wptr;
2380 const uint8_t *rptr;
2381 uint32_t i;
2382 uint32_t t32;
2383 uint8_t ret;
2384 threc *rec = fs_get_my_threc();
2385 t32 = strlen((const char *)path)+1;
2386 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETTRASHPATH,t32+8);
2387 if (wptr==NULL) {
2388 return LIZARDFS_ERROR_IO;
2389 }
2390 put32bit(&wptr,inode);
2391 put32bit(&wptr,t32);
2392 memcpy(wptr,path,t32);
2393 rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETTRASHPATH,&i);
2394 if (rptr==NULL) {
2395 ret = LIZARDFS_ERROR_IO;
2396 } else if (i==1) {
2397 ret = rptr[0];
2398 } else {
2399 setDisconnect(true);
2400 ret = LIZARDFS_ERROR_IO;
2401 }
2402 return ret;
2403 }
2404
fs_undel(uint32_t inode)2405 uint8_t fs_undel(uint32_t inode) {
2406 uint8_t *wptr;
2407 const uint8_t *rptr;
2408 uint32_t i;
2409 uint8_t ret;
2410 threc *rec = fs_get_my_threc();
2411 wptr = fs_createpacket(rec,CLTOMA_FUSE_UNDEL,4);
2412 if (wptr==NULL) {
2413 return LIZARDFS_ERROR_IO;
2414 }
2415 put32bit(&wptr,inode);
2416 rptr = fs_sendandreceive(rec,MATOCL_FUSE_UNDEL,&i);
2417 if (rptr==NULL) {
2418 ret = LIZARDFS_ERROR_IO;
2419 } else if (i==1) {
2420 ret = rptr[0];
2421 } else {
2422 setDisconnect(true);
2423 ret = LIZARDFS_ERROR_IO;
2424 }
2425 return ret;
2426 }
2427
fs_purge(uint32_t inode)2428 uint8_t fs_purge(uint32_t inode) {
2429 uint8_t *wptr;
2430 const uint8_t *rptr;
2431 uint32_t i;
2432 uint8_t ret;
2433 threc *rec = fs_get_my_threc();
2434 wptr = fs_createpacket(rec,CLTOMA_FUSE_PURGE,4);
2435 if (wptr==NULL) {
2436 return LIZARDFS_ERROR_IO;
2437 }
2438 put32bit(&wptr,inode);
2439 rptr = fs_sendandreceive(rec,MATOCL_FUSE_PURGE,&i);
2440 if (rptr==NULL) {
2441 ret = LIZARDFS_ERROR_IO;
2442 } else if (i==1) {
2443 ret = rptr[0];
2444 } else {
2445 setDisconnect(true);
2446 ret = LIZARDFS_ERROR_IO;
2447 }
2448 return ret;
2449 }
2450
fs_getxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gid,uint8_t nleng,const uint8_t * name,uint8_t mode,const uint8_t ** vbuff,uint32_t * vleng)2451 uint8_t fs_getxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gid,uint8_t nleng,const uint8_t *name,uint8_t mode,const uint8_t **vbuff,uint32_t *vleng) {
2452 uint8_t *wptr;
2453 const uint8_t *rptr;
2454 uint32_t i;
2455 uint8_t ret;
2456 threc *rec = fs_get_my_threc();
2457 if (masterversion < lizardfsVersion(1, 6, 29)) {
2458 return LIZARDFS_ERROR_ENOTSUP;
2459 }
2460 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETXATTR,15+nleng);
2461 if (wptr==NULL) {
2462 return LIZARDFS_ERROR_IO;
2463 }
2464 put32bit(&wptr,inode);
2465 put8bit(&wptr,opened);
2466 put32bit(&wptr,uid);
2467 put32bit(&wptr,gid);
2468 put8bit(&wptr,nleng);
2469 memcpy(wptr,name,nleng);
2470 wptr+=nleng;
2471 put8bit(&wptr,mode);
2472 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETXATTR,&i);
2473 if (rptr==NULL) {
2474 ret = LIZARDFS_ERROR_IO;
2475 } else if (i==1) {
2476 ret = rptr[0];
2477 } else if (i<4) {
2478 setDisconnect(true);
2479 ret = LIZARDFS_ERROR_IO;
2480 } else {
2481 *vleng = get32bit(&rptr);
2482 *vbuff = (mode==XATTR_GMODE_GET_DATA)?rptr:NULL;
2483 if ((mode==XATTR_GMODE_GET_DATA && i!=(*vleng)+4) || (mode==XATTR_GMODE_LENGTH_ONLY && i!=4)) {
2484 setDisconnect(true);
2485 ret = LIZARDFS_ERROR_IO;
2486 } else {
2487 ret = LIZARDFS_STATUS_OK;
2488 }
2489 }
2490 return ret;
2491 }
2492
fs_listxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gid,uint8_t mode,const uint8_t ** dbuff,uint32_t * dleng)2493 uint8_t fs_listxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gid,uint8_t mode,const uint8_t **dbuff,uint32_t *dleng) {
2494 uint8_t *wptr;
2495 const uint8_t *rptr;
2496 uint32_t i;
2497 uint8_t ret;
2498 threc *rec = fs_get_my_threc();
2499 if (masterversion < lizardfsVersion(1, 6, 29)) {
2500 return LIZARDFS_ERROR_ENOTSUP;
2501 }
2502 wptr = fs_createpacket(rec,CLTOMA_FUSE_GETXATTR,15);
2503 if (wptr==NULL) {
2504 return LIZARDFS_ERROR_IO;
2505 }
2506 put32bit(&wptr,inode);
2507 put8bit(&wptr,opened);
2508 put32bit(&wptr,uid);
2509 put32bit(&wptr,gid);
2510 put8bit(&wptr,0);
2511 put8bit(&wptr,mode);
2512 rptr = fs_sendandreceive(rec,MATOCL_FUSE_GETXATTR,&i);
2513 if (rptr==NULL) {
2514 ret = LIZARDFS_ERROR_IO;
2515 } else if (i==1) {
2516 ret = rptr[0];
2517 } else if (i<4) {
2518 setDisconnect(true);
2519 ret = LIZARDFS_ERROR_IO;
2520 } else {
2521 *dleng = get32bit(&rptr);
2522 *dbuff = (mode==XATTR_GMODE_GET_DATA)?rptr:NULL;
2523 if ((mode==XATTR_GMODE_GET_DATA && i!=(*dleng)+4) || (mode==XATTR_GMODE_LENGTH_ONLY && i!=4)) {
2524 setDisconnect(true);
2525 ret = LIZARDFS_ERROR_IO;
2526 } else {
2527 ret = LIZARDFS_STATUS_OK;
2528 }
2529 }
2530 return ret;
2531 }
2532
fs_setxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gid,uint8_t nleng,const uint8_t * name,uint32_t vleng,const uint8_t * value,uint8_t mode)2533 uint8_t fs_setxattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gid,uint8_t nleng,const uint8_t *name,uint32_t vleng,const uint8_t *value,uint8_t mode) {
2534 uint8_t *wptr;
2535 const uint8_t *rptr;
2536 uint32_t i;
2537 uint8_t ret;
2538 threc *rec = fs_get_my_threc();
2539 if (masterversion < lizardfsVersion(1, 6, 29)) {
2540 return LIZARDFS_ERROR_ENOTSUP;
2541 }
2542 if (mode>=XATTR_SMODE_REMOVE) {
2543 return LIZARDFS_ERROR_EINVAL;
2544 }
2545 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETXATTR,19+nleng+vleng);
2546 if (wptr==NULL) {
2547 return LIZARDFS_ERROR_IO;
2548 }
2549 put32bit(&wptr,inode);
2550 put8bit(&wptr,opened);
2551 put32bit(&wptr,uid);
2552 put32bit(&wptr,gid);
2553 put8bit(&wptr,nleng);
2554 memcpy(wptr,name,nleng);
2555 wptr+=nleng;
2556 put32bit(&wptr,vleng);
2557 memcpy(wptr,value,vleng);
2558 wptr+=vleng;
2559 put8bit(&wptr,mode);
2560 rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETXATTR,&i);
2561 if (rptr==NULL) {
2562 ret = LIZARDFS_ERROR_IO;
2563 } else if (i==1) {
2564 ret = rptr[0];
2565 } else {
2566 setDisconnect(true);
2567 ret = LIZARDFS_ERROR_IO;
2568 }
2569 return ret;
2570 }
2571
fs_removexattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gid,uint8_t nleng,const uint8_t * name)2572 uint8_t fs_removexattr(uint32_t inode,uint8_t opened,uint32_t uid,uint32_t gid,uint8_t nleng,const uint8_t *name) {
2573 uint8_t *wptr;
2574 const uint8_t *rptr;
2575 uint32_t i;
2576 uint8_t ret;
2577 threc *rec = fs_get_my_threc();
2578 if (masterversion < lizardfsVersion(1, 6, 29)) {
2579 return LIZARDFS_ERROR_ENOTSUP;
2580 }
2581 wptr = fs_createpacket(rec,CLTOMA_FUSE_SETXATTR,19+nleng);
2582 if (wptr==NULL) {
2583 return LIZARDFS_ERROR_IO;
2584 }
2585 put32bit(&wptr,inode);
2586 put8bit(&wptr,opened);
2587 put32bit(&wptr,uid);
2588 put32bit(&wptr,gid);
2589 put8bit(&wptr,nleng);
2590 memcpy(wptr,name,nleng);
2591 wptr+=nleng;
2592 put32bit(&wptr,0);
2593 put8bit(&wptr,XATTR_SMODE_REMOVE);
2594 rptr = fs_sendandreceive(rec,MATOCL_FUSE_SETXATTR,&i);
2595 if (rptr==NULL) {
2596 ret = LIZARDFS_ERROR_IO;
2597 } else if (i==1) {
2598 ret = rptr[0];
2599 } else {
2600 setDisconnect(true);
2601 ret = LIZARDFS_ERROR_IO;
2602 }
2603 return ret;
2604 }
2605
fs_deletacl(uint32_t inode,uint32_t uid,uint32_t gid,AclType type)2606 uint8_t fs_deletacl(uint32_t inode, uint32_t uid, uint32_t gid, AclType type) {
2607 threc* rec = fs_get_my_threc();
2608 auto message = cltoma::fuseDeleteAcl::build(rec->packetId, inode, uid, gid, type);
2609 if (!fs_lizcreatepacket(rec, message)) {
2610 return LIZARDFS_ERROR_IO;
2611 }
2612 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_DELETE_ACL, message)) {
2613 return LIZARDFS_ERROR_IO;
2614 }
2615 try {
2616 uint8_t status;
2617 uint32_t dummyMessageId;
2618 matocl::fuseDeleteAcl::deserialize(message.data(), message.size(), dummyMessageId, status);
2619 return status;
2620 } catch (Exception& ex) {
2621 fs_got_inconsistent("LIZ_MATOCL_DELETE_ACL", message.size(), ex.what());
2622 return LIZARDFS_ERROR_IO;
2623 }
2624 }
2625
fs_getacl(uint32_t inode,uint32_t uid,uint32_t gid,RichACL & acl,uint32_t & owner_id)2626 uint8_t fs_getacl(uint32_t inode, uint32_t uid, uint32_t gid, RichACL& acl, uint32_t &owner_id) {
2627 threc* rec = fs_get_my_threc();
2628 auto message = cltoma::fuseGetAcl::build(rec->packetId, inode, uid, gid, AclType::kRichACL);
2629 if (!fs_lizcreatepacket(rec, message)) {
2630 return LIZARDFS_ERROR_IO;
2631 }
2632 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_GET_ACL, message)) {
2633 return LIZARDFS_ERROR_IO;
2634 }
2635 try {
2636 PacketVersion packetVersion;
2637 deserializePacketVersionNoHeader(message, packetVersion);
2638 if (packetVersion == matocl::fuseGetAcl::kStatusPacketVersion) {
2639 uint8_t status;
2640 uint32_t dummy_msg_id;
2641 matocl::fuseGetAcl::deserialize(message.data(), message.size(), dummy_msg_id,
2642 status);
2643 if (status == LIZARDFS_STATUS_OK) {
2644 fs_got_inconsistent("LIZ_MATOCL_GET_ACL", message.size(),
2645 "version 0 and LIZARDFS_STATUS_OK");
2646 return LIZARDFS_ERROR_IO;
2647 }
2648 return status;
2649 } else if (packetVersion == matocl::fuseGetAcl::kRichACLResponsePacketVersion) {
2650 uint32_t dummy_msg_id;
2651 matocl::fuseGetAcl::deserialize(message.data(), message.size(), dummy_msg_id, owner_id, acl);
2652 return LIZARDFS_STATUS_OK;
2653 } else {
2654 fs_got_inconsistent("LIZ_MATOCL_GET_ACL", message.size(),
2655 "unknown version " + std::to_string(packetVersion));
2656 return LIZARDFS_ERROR_IO;
2657 }
2658 } catch (Exception& ex) {
2659 fs_got_inconsistent("LIZ_MATOCL_GET_ACL", message.size(), ex.what());
2660 return LIZARDFS_ERROR_IO;
2661 }
2662 }
2663
fs_setacl(uint32_t inode,uint32_t uid,uint32_t gid,const RichACL & acl)2664 uint8_t fs_setacl(uint32_t inode, uint32_t uid, uint32_t gid, const RichACL& acl) {
2665 threc* rec = fs_get_my_threc();
2666 auto message = cltoma::fuseSetAcl::build(rec->packetId, inode, uid, gid, acl);
2667 if (!fs_lizcreatepacket(rec, message)) {
2668 return LIZARDFS_ERROR_IO;
2669 }
2670 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_SET_ACL, message)) {
2671 return LIZARDFS_ERROR_IO;
2672 }
2673 try {
2674 uint8_t status;
2675 uint32_t dummy_msg_id;
2676 matocl::fuseSetAcl::deserialize(message.data(), message.size(), dummy_msg_id, status);
2677 return status;
2678 } catch (Exception& ex) {
2679 fs_got_inconsistent("LIZ_MATOCL_SET_ACL", message.size(), ex.what());
2680 return LIZARDFS_ERROR_IO;
2681 }
2682 }
2683
fs_setacl(uint32_t inode,uint32_t uid,uint32_t gid,AclType type,const AccessControlList & acl)2684 uint8_t fs_setacl(uint32_t inode, uint32_t uid, uint32_t gid, AclType type, const AccessControlList& acl) {
2685 threc* rec = fs_get_my_threc();
2686 auto message = cltoma::fuseSetAcl::build(rec->packetId, inode, uid, gid, type, acl);
2687 if (!fs_lizcreatepacket(rec, message)) {
2688 return LIZARDFS_ERROR_IO;
2689 }
2690 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_SET_ACL, message)) {
2691 return LIZARDFS_ERROR_IO;
2692 }
2693 try {
2694 uint8_t status;
2695 uint32_t dummy_msg_id;
2696 matocl::fuseSetAcl::deserialize(message.data(), message.size(), dummy_msg_id, status);
2697 return status;
2698 } catch (Exception& ex) {
2699 fs_got_inconsistent("LIZ_MATOCL_SET_ACL", message.size(), ex.what());
2700 return LIZARDFS_ERROR_IO;
2701 }
2702 }
2703
msgIdPtr(const MessageBuffer & buffer)2704 static uint32_t* msgIdPtr(const MessageBuffer& buffer) {
2705 PacketHeader header;
2706 deserializePacketHeader(buffer, header);
2707 uint32_t msgIdOffset = 0;
2708 if (header.isOldPacketType()) {
2709 msgIdOffset = serializedSize(PacketHeader());
2710 } else if (header.isLizPacketType()) {
2711 msgIdOffset = serializedSize(PacketHeader(), PacketVersion());
2712 } else {
2713 sassert(!"unrecognized packet header");
2714 }
2715 if (msgIdOffset + serializedSize(uint32_t()) > buffer.size()) {
2716 return nullptr;
2717 }
2718 return (uint32_t*) (buffer.data() + msgIdOffset);
2719 }
2720
fs_custom(MessageBuffer & buffer)2721 uint8_t fs_custom(MessageBuffer& buffer) {
2722 threc *rec = fs_get_my_threc();
2723 uint32_t *ptr = nullptr;
2724 ptr = msgIdPtr(buffer);
2725 if (!ptr) {
2726 // packet too short
2727 return LIZARDFS_ERROR_EINVAL;
2728 }
2729 const uint32_t origMsgIdBigEndian = *ptr;
2730 *ptr = htonl(rec->packetId);
2731 if (!fs_lizcreatepacket(rec, std::move(buffer))) {
2732 return LIZARDFS_ERROR_IO;
2733 }
2734 if (!fs_lizsendandreceive_any(rec, buffer)) {
2735 return LIZARDFS_ERROR_IO;
2736 }
2737 ptr = msgIdPtr(buffer);
2738 if (!ptr) {
2739 // reply too short
2740 return LIZARDFS_ERROR_EINVAL;
2741 }
2742 *ptr = origMsgIdBigEndian;
2743 return LIZARDFS_STATUS_OK;
2744 }
2745
fs_raw_sendandreceive(MessageBuffer & buffer,PacketHeader::Type expectedType)2746 uint8_t fs_raw_sendandreceive(MessageBuffer& buffer, PacketHeader::Type expectedType) {
2747 threc *rec = fs_get_my_threc();
2748 uint32_t *ptr = nullptr;
2749 ptr = msgIdPtr(buffer);
2750 if (!ptr) {
2751 // packet too short
2752 return LIZARDFS_ERROR_EINVAL;
2753 }
2754 *ptr = htonl(rec->packetId);
2755 if (!fs_lizcreatepacket(rec, std::move(buffer))) {
2756 return LIZARDFS_ERROR_IO;
2757 }
2758 if (!fs_lizsendandreceive(rec, expectedType, buffer)) {
2759 return LIZARDFS_ERROR_IO;
2760 }
2761 return LIZARDFS_STATUS_OK;
2762 }
2763
fs_send_custom(MessageBuffer buffer)2764 uint8_t fs_send_custom(MessageBuffer buffer) {
2765 threc *rec = fs_get_my_threc();
2766 if (!fs_lizcreatepacket(rec, std::move(buffer))) {
2767 return LIZARDFS_ERROR_IO;
2768 }
2769 if (!fs_threc_flush(rec)) {
2770 return LIZARDFS_ERROR_IO;
2771 }
2772 return LIZARDFS_STATUS_OK;
2773 }
2774
fs_register_packet_type_handler(PacketHeader::Type type,PacketHandler * handler)2775 bool fs_register_packet_type_handler(PacketHeader::Type type, PacketHandler *handler) {
2776 std::unique_lock<std::mutex> lock(perTypePacketHandlersLock);
2777 if (perTypePacketHandlers.count(type) > 0) {
2778 return false;
2779 }
2780 perTypePacketHandlers[type] = handler;
2781 return true;
2782 }
2783
fs_unregister_packet_type_handler(PacketHeader::Type type,PacketHandler * handler)2784 bool fs_unregister_packet_type_handler(PacketHeader::Type type, PacketHandler *handler) {
2785 std::unique_lock<std::mutex> lock(perTypePacketHandlersLock);
2786 PerTypePacketHandlers::iterator it = perTypePacketHandlers.find(type);
2787 if (it == perTypePacketHandlers.end()) {
2788 return false;
2789 }
2790 if (it->second != handler) {
2791 return false;
2792 }
2793 perTypePacketHandlers.erase(it);
2794 return true;
2795 }
2796
fs_flock_interrupt(const lzfs_locks::InterruptData & data)2797 void fs_flock_interrupt(const lzfs_locks::InterruptData &data) {
2798 threc *rec = fs_get_my_threc();
2799 auto message = cltoma::fuseFlock::build(rec->packetId, data);
2800 // is there anything we can do if send fails?
2801 fs_lizcreatepacket(rec, message);
2802 fs_lizsend(rec);
2803 }
2804
fs_setlk_interrupt(const lzfs_locks::InterruptData & data)2805 void fs_setlk_interrupt(const lzfs_locks::InterruptData &data) {
2806 threc *rec = fs_get_my_threc();
2807 auto message = cltoma::fuseSetlk::build(rec->packetId, data);
2808 // is there anything we can do if send fails?
2809 fs_lizcreatepacket(rec, message);
2810 fs_lizsend(rec);
2811 }
2812
fs_getlk(uint32_t inode,uint64_t owner,lzfs_locks::FlockWrapper & lock)2813 uint8_t fs_getlk(uint32_t inode, uint64_t owner, lzfs_locks::FlockWrapper &lock) {
2814 threc *rec = fs_get_my_threc();
2815
2816 auto message = cltoma::fuseGetlk::build(rec->packetId, inode, owner, lock);
2817
2818 if (!fs_lizcreatepacket(rec, message)) {
2819 return LIZARDFS_ERROR_IO;
2820 }
2821
2822 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_GETLK, message)) {
2823 return LIZARDFS_ERROR_IO;
2824 }
2825
2826 try {
2827 PacketVersion packet_version;
2828 deserializePacketVersionNoHeader(message, packet_version);
2829 if (packet_version == matocl::fuseGetlk::kStatusPacketVersion) {
2830 uint8_t status;
2831 uint32_t message_id;
2832 matocl::fuseGetlk::deserialize(message, message_id, status);
2833 return status;
2834 } else if (packet_version == matocl::fuseGetlk::kResponsePacketVersion) {
2835 uint32_t message_id;
2836 matocl::fuseGetlk::deserialize(message, message_id, lock);
2837 return LIZARDFS_STATUS_OK;
2838 } else {
2839 fs_got_inconsistent(
2840 "LIZ_MATOCL_GETLK",
2841 message.size(),
2842 "unknown version " + std::to_string(packet_version));
2843 return LIZARDFS_ERROR_IO;
2844 }
2845 } catch (Exception& ex) {
2846 fs_got_inconsistent("LIZ_MATOCL_GETLK", message.size(), ex.what());
2847 return LIZARDFS_ERROR_IO;
2848 }
2849 }
2850
fs_setlk_send(uint32_t inode,uint64_t owner,uint32_t reqid,const lzfs_locks::FlockWrapper & lock)2851 uint8_t fs_setlk_send(uint32_t inode, uint64_t owner, uint32_t reqid, const lzfs_locks::FlockWrapper &lock) {
2852 threc *rec = fs_get_my_threc();
2853
2854 auto message = cltoma::fuseSetlk::build(rec->packetId, inode, owner, reqid, lock);
2855
2856 if (!fs_lizcreatepacket(rec, message)) {
2857 return LIZARDFS_ERROR_IO;
2858 }
2859
2860 if (!fs_lizsend(rec)) {
2861 return LIZARDFS_ERROR_IO;
2862 }
2863
2864 return LIZARDFS_STATUS_OK;
2865 }
2866
fs_setlk_recv()2867 uint8_t fs_setlk_recv() {
2868 MessageBuffer message;
2869 threc* rec = fs_get_my_threc();
2870
2871 if (!fs_lizrecv(rec, LIZ_MATOCL_FUSE_SETLK, message)) {
2872 return LIZARDFS_ERROR_IO;
2873 }
2874
2875 try {
2876 PacketVersion packetVersion;
2877 deserializePacketVersionNoHeader(message, packetVersion);
2878 if (packetVersion == 0) {
2879 uint8_t status;
2880 uint32_t dummyMessageId;
2881 matocl::fuseSetlk::deserialize(message, dummyMessageId, status);
2882 return status;
2883 } else {
2884 fs_got_inconsistent(
2885 "LIZ_MATOCL_SETLK",
2886 message.size(),
2887 "unknown version " + std::to_string(packetVersion));
2888 return LIZARDFS_ERROR_IO;
2889 }
2890 } catch (Exception& ex) {
2891 fs_got_inconsistent("LIZ_MATOCL_SETLK", message.size(), ex.what());
2892 return LIZARDFS_ERROR_IO;
2893 }
2894 }
2895
fs_flock_send(uint32_t inode,uint64_t owner,uint32_t reqid,uint16_t op)2896 uint8_t fs_flock_send(uint32_t inode, uint64_t owner, uint32_t reqid, uint16_t op) {
2897 threc *rec = fs_get_my_threc();
2898
2899 auto message = cltoma::fuseFlock::build(rec->packetId, inode, owner, reqid, op);
2900
2901 if (!fs_lizcreatepacket(rec, message)) {
2902 return LIZARDFS_ERROR_IO;
2903 }
2904
2905 if (!fs_lizsend(rec)) {
2906 return LIZARDFS_ERROR_IO;
2907 }
2908
2909 return LIZARDFS_STATUS_OK;
2910 }
2911
fs_flock_recv()2912 uint8_t fs_flock_recv() {
2913 MessageBuffer message;
2914 threc* rec = fs_get_my_threc();
2915
2916 if (!fs_lizrecv(rec, LIZ_MATOCL_FUSE_FLOCK, message)) {
2917 return LIZARDFS_ERROR_IO;
2918 }
2919
2920 try {
2921 PacketVersion packetVersion;
2922 deserializePacketVersionNoHeader(message, packetVersion);
2923 if (packetVersion == 0) {
2924 uint8_t status;
2925 uint32_t dummyMessageId;
2926 matocl::fuseFlock::deserialize(message, dummyMessageId, status);
2927 return status;
2928 } else {
2929 fs_got_inconsistent(
2930 "LIZ_MATOCL_FLOCK",
2931 message.size(),
2932 "unknown version " + std::to_string(packetVersion));
2933 return LIZARDFS_ERROR_IO;
2934 }
2935 } catch (Exception& ex) {
2936 fs_got_inconsistent("LIZ_MATOCL_FLOCK", message.size(), ex.what());
2937 return LIZARDFS_ERROR_IO;
2938 }
2939 }
2940
fs_makesnapshot(uint32_t src_inode,uint32_t dst_inode,const std::string & dst_parent,uint32_t uid,uint32_t gid,uint8_t can_overwrite,LizardClient::JobId & job_id)2941 uint8_t fs_makesnapshot(uint32_t src_inode, uint32_t dst_inode, const std::string &dst_parent,
2942 uint32_t uid, uint32_t gid, uint8_t can_overwrite, LizardClient::JobId &job_id) {
2943 static const int kBatchSize = 1024;
2944 threc *rec = fs_get_my_threc();
2945 job_id = 0;
2946
2947 uint32_t msg_id;
2948 MessageBuffer response;
2949 auto request = cltoma::requestTaskId::build(rec->packetId);
2950 if (!fs_lizcreatepacket(rec, request)) {
2951 return LIZARDFS_ERROR_IO;
2952 }
2953 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_REQUEST_TASK_ID, response)) {
2954 return LIZARDFS_ERROR_IO;
2955 }
2956
2957 try {
2958 matocl::requestTaskId::deserialize(response, msg_id, job_id);
2959 } catch (Exception& ex) {
2960 fs_got_inconsistent("LIZ_MATOCL_FUSE_REQUEST_TASK_ID", request.size(), ex.what());
2961 job_id = 0;
2962 return LIZARDFS_ERROR_IO;
2963 }
2964
2965 request = cltoma::snapshot::build(rec->packetId, job_id, src_inode, dst_inode, dst_parent,
2966 uid, gid, can_overwrite, true, kBatchSize);
2967
2968 if (!fs_lizcreatepacket(rec, request)) {
2969 job_id = 0;
2970 return LIZARDFS_ERROR_IO;
2971 }
2972
2973 response.clear();
2974 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_SNAPSHOT, response)) {
2975 job_id = 0;
2976 return LIZARDFS_ERROR_IO;
2977 }
2978
2979 try {
2980 uint8_t status;
2981 matocl::snapshot::deserialize(response, msg_id, status);
2982 return status;
2983 } catch (Exception& ex) {
2984 fs_got_inconsistent("LIZ_MATOCL_FUSE_SNAPSHOT", request.size(), ex.what());
2985 job_id = 0;
2986 return LIZARDFS_ERROR_IO;
2987 }
2988 }
2989
fs_getgoal(uint32_t inode,std::string & goal)2990 uint8_t fs_getgoal(uint32_t inode, std::string &goal) {
2991 threc *rec = fs_get_my_threc();
2992
2993 goal.clear();
2994 auto message = cltoma::fuseGetGoal::build(rec->packetId, inode, GMODE_NORMAL);
2995
2996 if (!fs_lizcreatepacket(rec, message)) {
2997 return LIZARDFS_ERROR_IO;
2998 }
2999
3000 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_GETGOAL, message)) {
3001 return LIZARDFS_ERROR_IO;
3002 }
3003
3004 try {
3005 PacketVersion packet_version;
3006 deserializePacketVersionNoHeader(message, packet_version);
3007 if (packet_version == matocl::fuseGetGoal::kStatusPacketVersion) {
3008 uint8_t status;
3009 uint32_t dummy_message_id;
3010 matocl::fuseGetGoal::deserialize(message, dummy_message_id, status);
3011 return status;
3012 } else if (packet_version == matocl::fuseGetGoal::kResponsePacketVersion) {
3013 std::vector<FuseGetGoalStats> goalsStats;
3014 uint32_t messageId;
3015 matocl::fuseGetGoal::deserialize(message, messageId, goalsStats);
3016 if (goalsStats.size() != 1) {
3017 return LIZARDFS_ERROR_EINVAL;
3018 }
3019 goal = goalsStats[0].goalName;
3020 return LIZARDFS_STATUS_OK;
3021 } else {
3022 return LIZARDFS_ERROR_EINVAL;
3023 }
3024 } catch (Exception& ex) {
3025 fs_got_inconsistent("LIZ_MATOCL_FUSE_GETGOAL", message.size(), ex.what());
3026 return LIZARDFS_ERROR_IO;
3027 }
3028 }
3029
fs_setgoal(uint32_t inode,uint32_t uid,const std::string & goal_name,uint8_t smode)3030 uint8_t fs_setgoal(uint32_t inode, uint32_t uid, const std::string &goal_name, uint8_t smode) {
3031 threc *rec = fs_get_my_threc();
3032
3033 auto message = cltoma::fuseSetGoal::build(rec->packetId, inode, uid, goal_name, smode);
3034
3035 if (!fs_lizcreatepacket(rec, message)) {
3036 return LIZARDFS_ERROR_IO;
3037 }
3038
3039 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_FUSE_SETGOAL, message)) {
3040 return LIZARDFS_ERROR_IO;
3041 }
3042
3043 try {
3044 PacketVersion packet_version;
3045 deserializePacketVersionNoHeader(message, packet_version);
3046 if (packet_version == matocl::fuseSetGoal::kStatusPacketVersion) {
3047 uint8_t status;
3048 uint32_t dummy_message_id;
3049 matocl::fuseSetGoal::deserialize(message, dummy_message_id, status);
3050 return status;
3051 } else if (packet_version == matocl::fuseSetGoal::kResponsePacketVersion) {
3052 return LIZARDFS_STATUS_OK;
3053 } else {
3054 return LIZARDFS_ERROR_EINVAL;
3055 }
3056 } catch (Exception& ex) {
3057 fs_got_inconsistent("LIZ_MATOCL_FUSE_SETGOAL", message.size(), ex.what());
3058 return LIZARDFS_ERROR_IO;
3059 }
3060 }
3061
fs_getchunksinfo(uint32_t uid,uint32_t gid,uint32_t inode,uint32_t chunk_index,uint32_t chunk_count,std::vector<ChunkWithAddressAndLabel> & chunks)3062 uint8_t fs_getchunksinfo(uint32_t uid, uint32_t gid, uint32_t inode, uint32_t chunk_index,
3063 uint32_t chunk_count, std::vector<ChunkWithAddressAndLabel> &chunks) {
3064 threc *rec = fs_get_my_threc();
3065
3066 auto message = cltoma::chunksInfo::build(rec->packetId, uid, gid, inode, chunk_index, chunk_count);
3067
3068 if (!fs_lizcreatepacket(rec, message)) {
3069 return LIZARDFS_ERROR_IO;
3070 }
3071
3072 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_CHUNKS_INFO, message)) {
3073 return LIZARDFS_ERROR_IO;
3074 }
3075
3076 try {
3077 PacketVersion packet_version;
3078 deserializePacketVersionNoHeader(message, packet_version);
3079 if (packet_version == matocl::fuseSetGoal::kStatusPacketVersion) {
3080 uint8_t status;
3081 uint32_t message_id;
3082 matocl::chunksInfo::deserialize(message, message_id, status);
3083 return status;
3084 } else if (packet_version == matocl::fuseSetGoal::kResponsePacketVersion) {
3085 uint32_t message_id;
3086 matocl::chunksInfo::deserialize(message, message_id, chunks);
3087 return LIZARDFS_STATUS_OK;
3088 } else {
3089 return LIZARDFS_ERROR_EINVAL;
3090 }
3091 } catch (Exception& ex) {
3092 fs_got_inconsistent("LIZ_MATOCL_CHUNKS_INFO", message.size(), ex.what());
3093 return LIZARDFS_ERROR_IO;
3094 }
3095 }
3096
fs_getchunkservers(std::vector<ChunkserverListEntry> & chunkservers)3097 uint8_t fs_getchunkservers(std::vector<ChunkserverListEntry> &chunkservers) {
3098 threc *rec = fs_get_my_threc();
3099 uint32_t message_id;
3100
3101 auto message = cltoma::cservList::build(rec->packetId, true);
3102
3103 if (!fs_lizcreatepacket(rec, message)) {
3104 return LIZARDFS_ERROR_IO;
3105 }
3106
3107 if (!fs_lizsendandreceive(rec, LIZ_MATOCL_CSERV_LIST, message)) {
3108 return LIZARDFS_ERROR_IO;
3109 }
3110
3111 chunkservers.clear();
3112 matocl::cservList::deserialize(message, message_id, chunkservers);
3113 return LIZARDFS_STATUS_OK;
3114 }
3115