├── .gitattributes ├── .gitignore ├── README.md ├── img ├── lab1_part1_structure.png └── lab1_part2_structure.png └── yfs ├── .gitignore ├── .vscode └── settings.json ├── GNUmakefile ├── datanode.cc ├── datanode.h ├── datanode_base.cc ├── demo_client.cc ├── demo_protocol.h ├── demo_server.cc ├── extent_client.cc ├── extent_client.h ├── extent_protocol.h ├── extent_server.cc ├── extent_server.h ├── extent_smain.cc ├── fuse.cc ├── gettime.cc ├── gettime.h ├── grade.sh ├── handle.cc ├── handle.h ├── hrpc.h ├── inode_manager.cc ├── inode_manager.h ├── lab4.tgz ├── lang ├── algorithm.h └── verify.h ├── lock_client.cc ├── lock_client.h ├── lock_client_cache.cc ├── lock_client_cache.h ├── lock_demo.cc ├── lock_protocol.h ├── lock_server.cc ├── lock_server.h ├── lock_server_cache.cc ├── lock_server_cache.h ├── lock_smain.cc ├── lock_tester.cc ├── namenode.cc ├── namenode.h ├── namenode_base.cc ├── part1_tester.cc ├── part2_tester.sh ├── proto ├── common.proto ├── datanode.proto ├── namenode.proto └── output │ ├── common.pb.cc │ ├── common.pb.h │ ├── datanode.pb.cc │ ├── datanode.pb.h │ ├── google │ └── protobuf │ │ ├── any.h │ │ ├── any.pb.h │ │ ├── any.proto │ │ ├── api.pb.h │ │ ├── api.proto │ │ ├── arena.h │ │ ├── arenastring.h │ │ ├── descriptor.h │ │ ├── descriptor.pb.h │ │ ├── descriptor.proto │ │ ├── descriptor_database.h │ │ ├── duration.pb.h │ │ ├── duration.proto │ │ ├── dynamic_message.h │ │ ├── empty.pb.h │ │ ├── empty.proto │ │ ├── extension_set.h │ │ ├── field_mask.pb.h │ │ ├── field_mask.proto │ │ ├── generated_enum_reflection.h │ │ ├── generated_enum_util.h │ │ ├── generated_message_reflection.h │ │ ├── generated_message_util.h │ │ ├── io │ │ ├── coded_stream.h │ │ ├── gzip_stream.h │ │ ├── printer.h │ │ ├── strtod.h │ │ ├── tokenizer.h │ │ ├── zero_copy_stream.h │ │ ├── zero_copy_stream_impl.h │ │ └── zero_copy_stream_impl_lite.h │ │ ├── map.h │ │ ├── map_entry.h │ │ ├── map_entry_lite.h │ │ ├── map_field.h │ │ ├── map_field_inl.h │ │ ├── map_field_lite.h │ │ ├── map_type_handler.h │ │ ├── message.h │ │ ├── message_lite.h │ │ ├── metadata.h │ │ ├── reflection.h │ │ ├── reflection_ops.h │ │ ├── repeated_field.h │ │ ├── service.h │ │ ├── source_context.pb.h │ │ ├── source_context.proto │ │ ├── struct.pb.h │ │ ├── struct.proto │ │ ├── stubs │ │ ├── atomic_sequence_num.h │ │ ├── atomicops.h │ │ ├── atomicops_internals_arm64_gcc.h │ │ ├── atomicops_internals_arm_gcc.h │ │ ├── atomicops_internals_arm_qnx.h │ │ ├── atomicops_internals_atomicword_compat.h │ │ ├── atomicops_internals_generic_gcc.h │ │ ├── atomicops_internals_macosx.h │ │ ├── atomicops_internals_mips_gcc.h │ │ ├── atomicops_internals_pnacl.h │ │ ├── atomicops_internals_power.h │ │ ├── atomicops_internals_ppc_gcc.h │ │ ├── atomicops_internals_s390_gcc.h │ │ ├── atomicops_internals_solaris.h │ │ ├── atomicops_internals_tsan.h │ │ ├── atomicops_internals_x86_gcc.h │ │ ├── atomicops_internals_x86_msvc.h │ │ ├── bytestream.h │ │ ├── callback.h │ │ ├── casts.h │ │ ├── common.h │ │ ├── fastmem.h │ │ ├── hash.h │ │ ├── logging.h │ │ ├── macros.h │ │ ├── mutex.h │ │ ├── once.h │ │ ├── platform_macros.h │ │ ├── port.h │ │ ├── scoped_ptr.h │ │ ├── shared_ptr.h │ │ ├── singleton.h │ │ ├── status.h │ │ ├── stl_util.h │ │ ├── stringpiece.h │ │ ├── template_util.h │ │ └── type_traits.h │ │ ├── text_format.h │ │ ├── timestamp.pb.h │ │ ├── timestamp.proto │ │ ├── type.pb.h │ │ ├── type.proto │ │ ├── unknown_field_set.h │ │ ├── util │ │ ├── field_comparator.h │ │ ├── field_mask_util.h │ │ ├── json_util.h │ │ ├── message_differencer.h │ │ ├── time_util.h │ │ ├── type_resolver.h │ │ └── type_resolver_util.h │ │ ├── wire_format.h │ │ ├── wire_format_lite.h │ │ ├── wire_format_lite_inl.h │ │ ├── wrappers.pb.h │ │ └── wrappers.proto │ ├── namenode.pb.cc │ └── namenode.pb.h ├── readme ├── rpc ├── connection.h ├── fifo.h ├── jsl_log.h ├── marshall.h ├── method_thread.h ├── pollmgr.h ├── rpc.h ├── slock.h └── thr_pool.h ├── start.sh ├── stop.sh ├── test-lab-3-a.c ├── test-lab-3-b.c ├── test-lab1-part2-a.pl ├── test-lab1-part2-b.pl ├── test-lab1-part2-c.pl ├── test-lab1-part2-d.sh ├── test-lab1-part2-e.sh ├── test-lab1-part2-f.sh ├── test-lab2-part1-a.pl ├── test-lab2-part1-b.pl ├── test-lab2-part1-c.pl ├── test-lab2-part1-d.sh ├── test-lab2-part1-e.sh ├── test-lab2-part1-f.sh ├── test-lab2-part1-g.c ├── test-lab2-part2-a.c ├── test-lab2-part2-b.c ├── test-lab4-common.sh ├── test-lab4-part0.sh ├── test-lab4-part1.sh ├── test-lab4-part2.sh ├── test-lab4-part3.sh ├── threader.h ├── tprintf.h ├── yfs_client.cc └── yfs_client.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # yfs lab 2 | MIT 6.033, implement a distributed file system 3 | - To run this lab, you need to use a computer that has the FUSE module, library, and headers installed 4 | - You should be able to install these on your own machine by following the instructions at [fuse.sourceforge.net](https://github.com/libfuse/libfuse). 5 | 6 | ## [lab 1 & lab 2](https://github.com/TactfulYuu/FileSystem-yfs/tree/lab2) 7 | ### Implement a basic file system 8 | - Mainly focus on implementing parts shown in this image 9 | ![Lab1 Part 2](https://github.com/TactfulYuu/yfs-lab/blob/master/img/lab1_part2_structure.png) 10 | ### Implement an inode manager to support the file system 11 | - In this part, I implement functions in Inode_manager.cc & Extent_server.cc & Extent_client.cc to provide support for yfs APIs 12 | - Implement disk::read_block and disk::write_block inode_manager::alloc_inode andinode_manager::getattr, to support CREATE and GETATTR APIs 13 | - implement inode_manager::write_file, inode_manager::read_file, block_manager::alloc_block, block_manager::free_block, to support PUT and GET APIs 14 | - implement inode_manager::remove_file and inode_manager::free_inode, to support REMOVE API 15 | ### Start the file system implementation by getting some basic operations to work 16 | - In this part, I implement yfs APIs in Yfs_client.cc based on the functions in Inode_manager.cc & Extent_server.cc & Extent_client.cc 17 | - yfs APIs: CREATE/MKNOD, LOOKUP, READDIR, SETATTR, WRITE, READ, MKDIR, UNLINK, SYMLINK and READLINK 18 | ### Distributed FileSystem 19 | - In this part, I write an RPC system to implement distributed file system. A server uses the RPC library by creating an RPC server object listening on a port and registering various RPC handlers. A client creates a RPC client object, asks for it to be connected to the demo_server's address and port, and invokes RPC calls. 20 | - And I implement a lock server to ensure the correctness of the distributed file system. At any point in time, there is at most one client holding a lock with a given identifier. 21 | - The lock server is based on the principle of ticket lock. Each RPC procedure is identified by a unique procedure number. 22 | - Acquire lock in the correct place in yfs_client to ensure the atomicity of file system. 23 | ## [lab 3](https://github.com/TactfulYuu/FileSystem-yfs/tree/lab3) 24 | ### Design the Protocol 25 | - First, make a design of the lock state before implement the lock protocol. Here is the five states of lock: 26 | - none: client knows nothing about this lock 27 | - free: client owns the lock and no thread has it 28 | - locked: client owns the lock and a thread has it 29 | - acquiring: the client is acquiring ownership 30 | - releasing: the client is releasing ownership 31 | - Here is some rules of the lock protocol: 32 | - A single client may have multiple threads waiting for the same lock, but only one thread per client is allowed to be interacting with the server. So only one thread per client can acquire the lock. Once that thread release the lock, it can wake up other threads and one of these threads can acquire the lock. Thread can be identified by its thread id. 33 | - **Lock Protocol**: When a client asks for a lock with an acquire request, the server grants the lock and responds with OK if the lock is not owned by another client (lock's state is **free**). If the lock's state is not **free**, and there are other clients waiting for the lock, the server responds with a RETRY. Otherwise, the server sends a revoke request to the owner of the lock, and waits for the lock to be released by the owner. Finally, the server sends a retry to the next waiting client, grants the lock and responds with OK. 34 | - **Lock Cache**: Once a client has acquired a lock, the client the lock in its cache (client keeps the lock instead of sending a release request to the server when a thread of the client releases the lock). The client can grant the lock to other threads on the same client without interacting with the server. 35 | - **Rovoke Request**: The server sends the client a revoke request to get the lock back. This request tells the client that it should send the lock back to the server when it releases the lock or right now if no thread on the client is holding the lock. 36 | ## [lab 4](https://github.com/TactfulYuu/FileSystem-yfs/tree/lab4) 37 | - Deploy this distributed file system to Tencent Cloud Server. 38 | - Fix some bugs in inode_manager: 39 | - Change the data structure of bitmap. 40 | - Update the point when appending blocks. The original design is updating the point after appending is finished. But this design will cause error after consecutive appending. 41 | -------------------------------------------------------------------------------- /img/lab1_part1_structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CaranthirLjh/FileSystem-yfs/0e2a77e2a33aa7fc749cd31b960ae00d757a6c35/img/lab1_part1_structure.png -------------------------------------------------------------------------------- /img/lab1_part2_structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CaranthirLjh/FileSystem-yfs/0e2a77e2a33aa7fc749cd31b960ae00d757a6c35/img/lab1_part2_structure.png -------------------------------------------------------------------------------- /yfs/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.d 3 | lab1_tester 4 | yfs_client1.log 5 | yfs_client2.log 6 | lock_server.log 7 | extent_server.log 8 | foo.txt.yfs1 9 | foo.txt.yfs2 10 | tmprand 11 | yfs_client 12 | extent_server 13 | datanode 14 | namenode 15 | lock_server 16 | /proto/output/*.o 17 | /part1_tester 18 | /app_public_ip 19 | *.log 20 | -------------------------------------------------------------------------------- /yfs/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "array": "cpp", 4 | "atomic": "cpp", 5 | "*.tcc": "cpp", 6 | "cctype": "cpp", 7 | "clocale": "cpp", 8 | "cmath": "cpp", 9 | "cstddef": "cpp", 10 | "cstdint": "cpp", 11 | "cstdio": "cpp", 12 | "cstdlib": "cpp", 13 | "cwchar": "cpp", 14 | "cwctype": "cpp", 15 | "deque": "cpp", 16 | "list": "cpp", 17 | "unordered_map": "cpp", 18 | "vector": "cpp", 19 | "exception": "cpp", 20 | "fstream": "cpp", 21 | "initializer_list": "cpp", 22 | "iosfwd": "cpp", 23 | "iostream": "cpp", 24 | "istream": "cpp", 25 | "limits": "cpp", 26 | "memory": "cpp", 27 | "new": "cpp", 28 | "optional": "cpp", 29 | "ostream": "cpp", 30 | "sstream": "cpp", 31 | "stdexcept": "cpp", 32 | "streambuf": "cpp", 33 | "string_view": "cpp", 34 | "system_error": "cpp", 35 | "cinttypes": "cpp", 36 | "type_traits": "cpp", 37 | "tuple": "cpp", 38 | "typeinfo": "cpp", 39 | "utility": "cpp" 40 | } 41 | } -------------------------------------------------------------------------------- /yfs/datanode.cc: -------------------------------------------------------------------------------- 1 | #include "datanode.h" 2 | #include 3 | #include "extent_client.h" 4 | #include 5 | #include 6 | #include "threader.h" 7 | 8 | using namespace std; 9 | 10 | int DataNode::init(const string &extent_dst, const string &namenode, const struct sockaddr_in *bindaddr) { 11 | cout<<"DataNode::init data node:"<sin_addr)); 16 | id.set_hostname(GetHostname()); 17 | id.set_datanodeuuid(GenerateUUID()); 18 | id.set_xferport(ntohs(bindaddr->sin_port)); 19 | id.set_infoport(0); 20 | id.set_ipcport(0); 21 | 22 | // Save namenode address and connect 23 | make_sockaddr(namenode.c_str(), &namenode_addr); 24 | if (!ConnectToNN()) { 25 | delete ec; 26 | ec = NULL; 27 | return -1; 28 | } 29 | 30 | // Register on namenode 31 | if (!RegisterOnNamenode()) { 32 | delete ec; 33 | ec = NULL; 34 | close(namenode_conn); 35 | namenode_conn = -1; 36 | return -1; 37 | } 38 | 39 | /* Add your initialization here */ 40 | NewThread(this,&DataNode::Heartbeat); 41 | 42 | if (ec->put(1, "") != extent_protocol::OK) 43 | printf("error init root dir\n"); // XYB: init root dir 44 | 45 | return 0; 46 | } 47 | 48 | void DataNode::Heartbeat() 49 | { 50 | while(true) 51 | { 52 | SendHeartbeat(); 53 | sleep(1); 54 | } 55 | } 56 | 57 | bool DataNode::ReadBlock(blockid_t bid, uint64_t offset, uint64_t len, string &buf) { 58 | cout<<"DataNode::ReadBlock: Start! bid:"<read_block(bid,block_buf); 63 | // if(r_readblock!=extent_protocol::OK) 64 | // { 65 | // cout<<"DataNode::ReadBlock: Read block fail."<block_buf.size()) 70 | { 71 | buf=""; 72 | } 73 | else 74 | { 75 | buf=block_buf.substr(offset,len); 76 | } 77 | cout<<"DataNode::ReadBlock: offset:"<read_block(bid,block_buf); 88 | // if(r_readblock!=extent_protocol::OK) 89 | // { 90 | // cout<<"DataNode::WriteBlock: Read block fail."<read_block(bid,read_content); 96 | string write_content= read_content.substr(0,offset)+buf+read_content.substr(offset+len); 97 | ec->write_block(bid,write_content); 98 | 99 | return true; 100 | } 101 | 102 | -------------------------------------------------------------------------------- /yfs/datanode.h: -------------------------------------------------------------------------------- 1 | #ifndef DATANODE_H_ 2 | #define DATANODE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "extent_protocol.h" 10 | #include 11 | 12 | class extent_client; 13 | 14 | class DataNode { 15 | private: 16 | extent_client *ec; 17 | struct sockaddr_in namenode_addr; 18 | int namenode_conn; 19 | bool ConnectToNN(); 20 | bool RegisterOnNamenode(); 21 | static std::string GetHostname(); 22 | static std::string GenerateUUID(); 23 | DatanodeIDProto id; 24 | bool ReadBlock(blockid_t bid, uint64_t offset, uint64_t len, std::string &buf); 25 | bool WriteBlock(blockid_t bid, uint64_t offset, uint64_t len, const std::string &buf); 26 | bool SendHeartbeat(); 27 | void Heartbeat(); 28 | 29 | /* Feel free to add your member variables/functions here */ 30 | public: 31 | int init(const std::string &extent_dst, const std::string &namenode, const struct sockaddr_in *bindaddr); 32 | bool _ReadBlock(google::protobuf::io::CodedInputStream &is, google::protobuf::io::CodedOutputStream &os, google::protobuf::io::FileOutputStream &raw_os); 33 | bool _WriteBlock(google::protobuf::io::CodedInputStream &is, google::protobuf::io::CodedOutputStream &os, google::protobuf::io::FileOutputStream &raw_os); 34 | bool _TransferBlock(google::protobuf::io::CodedInputStream &is, google::protobuf::io::CodedOutputStream &os); 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /yfs/demo_client.cc: -------------------------------------------------------------------------------- 1 | // demo client 2 | 3 | #include 4 | #include "demo_protocol.h" 5 | #include "rpc.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | // Client interface to the demo server 13 | class demo_client { 14 | protected: 15 | rpcc *cl; 16 | public: 17 | demo_client(std::string d); 18 | virtual ~demo_client() {}; 19 | virtual demo_protocol::status stat(demo_protocol::demoVar); 20 | }; 21 | 22 | demo_client::demo_client(std::string dst) 23 | { 24 | sockaddr_in dstsock; 25 | make_sockaddr(dst.c_str(), &dstsock); 26 | cl = new rpcc(dstsock); 27 | if (cl->bind() < 0) { 28 | printf("demo_client: call bind\n"); 29 | } 30 | } 31 | 32 | int 33 | demo_client::stat(demo_protocol::demoVar var) 34 | { 35 | int r; 36 | demo_protocol::status ret = cl->call(demo_protocol::stat, cl->id(), var, r); 37 | VERIFY (ret == demo_protocol::OK); 38 | return r; 39 | } 40 | 41 | 42 | #include "demo_protocol.h" 43 | #include "rpc.h" 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | std::string dst; 50 | demo_client *dc; 51 | 52 | int 53 | main(int argc, char *argv[]) 54 | { 55 | int r; 56 | 57 | if(argc != 2){ 58 | fprintf(stderr, "Usage: %s [host:]port\n", argv[0]); 59 | exit(1); 60 | } 61 | 62 | dst = argv[1]; 63 | dc = new demo_client(dst); 64 | r = dc->stat(1); 65 | printf ("stat returned %d\n", r); 66 | } 67 | -------------------------------------------------------------------------------- /yfs/demo_protocol.h: -------------------------------------------------------------------------------- 1 | // demo protocol 2 | 3 | #ifndef demo_protocol_h 4 | #define demo_protocol_h 5 | 6 | #include "rpc.h" 7 | 8 | class demo_protocol { 9 | public: 10 | enum xxstatus { OK, RETRY, RPCERR, NOENT, IOERR }; 11 | typedef int status; 12 | typedef unsigned long long demoVar; 13 | enum rpc_numbers { 14 | stat = 0x7001, 15 | rpcA, 16 | rpcB 17 | }; 18 | }; 19 | 20 | #endif -------------------------------------------------------------------------------- /yfs/demo_server.cc: -------------------------------------------------------------------------------- 1 | // demo server 2 | 3 | #include 4 | #include 5 | #include 6 | #include "demo_protocol.h" 7 | #include "rpc.h" 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | class demo_server { 14 | public: 15 | demo_server() {}; 16 | ~demo_server() {}; 17 | demo_protocol::status stat(int clt, demo_protocol::demoVar a, int &); 18 | // for illustration only 19 | // demo_protocol::status rpcA(int clt, demo_protocol::demoVar a, int &); 20 | // demo_protocol::status rpcB(int clt, demo_protocol::demoVar a, int &); 21 | }; 22 | 23 | demo_protocol::status 24 | demo_server::stat(int clt, demo_protocol::demoVar var, int &r) 25 | { 26 | demo_protocol::status ret = demo_protocol::OK; 27 | printf("stat request from clt %d\n", clt); 28 | r = 0; 29 | return ret; 30 | } 31 | 32 | 33 | // Main loop of demo_server 34 | 35 | int main(int argc, char const *argv[]) 36 | { 37 | int count = 0; 38 | 39 | setvbuf(stdout, NULL, _IONBF, 0); 40 | setvbuf(stderr, NULL, _IONBF, 0); 41 | 42 | srandom(getpid()); 43 | 44 | if(argc != 2){ 45 | fprintf(stderr, "Usage: %s port\n", argv[0]); 46 | exit(1); 47 | } 48 | 49 | char *count_env = getenv("RPC_COUNT"); 50 | if(count_env != NULL){ 51 | count = atoi(count_env); 52 | } 53 | 54 | demo_server ds; 55 | rpcs server(atoi(argv[1]), count); 56 | server.reg(demo_protocol::stat, &ds, &demo_server::stat); 57 | 58 | while(1) 59 | sleep(1000); 60 | } 61 | -------------------------------------------------------------------------------- /yfs/extent_client.cc: -------------------------------------------------------------------------------- 1 | // RPC stubs for clients to talk to extent_server 2 | 3 | #include "extent_client.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | extent_client::extent_client(std::string dst) 11 | { 12 | sockaddr_in dstsock; 13 | make_sockaddr(dst.c_str(), &dstsock); 14 | cl = new rpcc(dstsock); 15 | if (cl->bind() != 0) { 16 | printf("extent_client: bind failed\n"); 17 | } 18 | } 19 | 20 | // a demo to show how to use RPC 21 | extent_protocol::status 22 | extent_client::create(uint32_t type, extent_protocol::extentid_t &id) 23 | { 24 | extent_protocol::status ret = extent_protocol::OK; 25 | // Your lab2 part1 code goes here 26 | ret = cl->call(extent_protocol::create,type,id); 27 | //VERIFY(ret == extent_protocol::OK); 28 | 29 | return ret; 30 | } 31 | 32 | extent_protocol::status 33 | extent_client::get(extent_protocol::extentid_t eid, std::string &buf) 34 | { 35 | extent_protocol::status ret = extent_protocol::OK; 36 | // Your lab2 part1 code goes here 37 | ret = cl->call(extent_protocol::get,eid,buf); 38 | //VERIFY(ret == extent_protocol::OK); 39 | 40 | return ret; 41 | } 42 | 43 | extent_protocol::status 44 | extent_client::getattr(extent_protocol::extentid_t eid, 45 | extent_protocol::attr &attr) 46 | { 47 | extent_protocol::status ret = extent_protocol::OK; 48 | ret = cl->call(extent_protocol::getattr, eid, attr); 49 | return ret; 50 | } 51 | 52 | extent_protocol::status 53 | extent_client::put(extent_protocol::extentid_t eid, std::string buf) 54 | { 55 | extent_protocol::status ret = extent_protocol::OK; 56 | // Your lab2 part1 code goes here 57 | int put_number=0; 58 | ret = cl->call(extent_protocol::put,eid,buf,put_number); 59 | VERIFY(ret == extent_protocol::OK); 60 | 61 | return ret; 62 | } 63 | 64 | extent_protocol::status 65 | extent_client::remove(extent_protocol::extentid_t eid) 66 | { 67 | extent_protocol::status ret = extent_protocol::OK; 68 | // Your lab2 part1 code goes here 69 | int remove_number=0; 70 | ret = cl->call(extent_protocol::remove,eid,remove_number); 71 | VERIFY(ret == extent_protocol::OK); 72 | 73 | return ret; 74 | } 75 | 76 | extent_protocol::status 77 | extent_client::get_block_ids(extent_protocol::extentid_t eid, std::list &block_ids) 78 | { 79 | extent_protocol::status ret = extent_protocol::OK; 80 | ret = cl->call(extent_protocol::get_block_ids, eid, block_ids); 81 | return ret; 82 | } 83 | 84 | extent_protocol::status 85 | extent_client::read_block(blockid_t bid, std::string &buf) 86 | { 87 | extent_protocol::status ret = extent_protocol::OK; 88 | ret = cl->call(extent_protocol::read_block, bid, buf); 89 | return ret; 90 | } 91 | 92 | extent_protocol::status 93 | extent_client::write_block(blockid_t bid, const std::string &buf) 94 | { 95 | extent_protocol::status ret = extent_protocol::OK; 96 | int r; 97 | ret = cl->call(extent_protocol::write_block, bid, buf, r); 98 | return ret; 99 | } 100 | 101 | extent_protocol::status 102 | extent_client::append_block(extent_protocol::extentid_t eid, blockid_t &bid) 103 | { 104 | extent_protocol::status ret = extent_protocol::OK; 105 | ret = cl->call(extent_protocol::append_block, eid, bid); 106 | return ret; 107 | } 108 | 109 | extent_protocol::status 110 | extent_client::complete(extent_protocol::extentid_t eid, uint32_t size) 111 | { 112 | extent_protocol::status ret = extent_protocol::OK; 113 | int r; 114 | ret = cl->call(extent_protocol::complete, eid, size, r); 115 | return ret; 116 | } 117 | 118 | -------------------------------------------------------------------------------- /yfs/extent_client.h: -------------------------------------------------------------------------------- 1 | // extent client interface. 2 | 3 | #ifndef extent_client_h 4 | #define extent_client_h 5 | 6 | #include 7 | #include "extent_protocol.h" 8 | #include "extent_server.h" 9 | 10 | class extent_client { 11 | private: 12 | rpcc *cl; 13 | 14 | public: 15 | extent_client(std::string dst); 16 | 17 | extent_protocol::status create(uint32_t type, extent_protocol::extentid_t &eid); 18 | extent_protocol::status get(extent_protocol::extentid_t eid, 19 | std::string &buf); 20 | extent_protocol::status getattr(extent_protocol::extentid_t eid, 21 | extent_protocol::attr &a); 22 | extent_protocol::status put(extent_protocol::extentid_t eid, std::string buf); 23 | extent_protocol::status remove(extent_protocol::extentid_t eid); 24 | extent_protocol::status get_block_ids(extent_protocol::extentid_t eid, std::list &block_ids); 25 | extent_protocol::status read_block(blockid_t bid, std::string &buf); 26 | extent_protocol::status write_block(blockid_t bid, const std::string &buf); 27 | extent_protocol::status append_block(extent_protocol::extentid_t eid, blockid_t &bid); 28 | extent_protocol::status complete(extent_protocol::extentid_t eid, uint32_t size); 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /yfs/extent_protocol.h: -------------------------------------------------------------------------------- 1 | // extent wire protocol 2 | 3 | #ifndef extent_protocol_h 4 | #define extent_protocol_h 5 | 6 | #include "rpc.h" 7 | 8 | typedef uint32_t blockid_t; 9 | 10 | class extent_protocol { 11 | public: 12 | typedef int status; 13 | typedef unsigned long long extentid_t; 14 | enum xxstatus { OK, RPCERR, NOENT, IOERR }; 15 | enum rpc_numbers { 16 | put = 0x6001, 17 | get, 18 | getattr, 19 | remove, 20 | create, 21 | //new interface: 22 | get_block_ids, 23 | read_block, 24 | write_block, 25 | append_block, 26 | complete 27 | }; 28 | 29 | enum types { 30 | T_DIR = 1, 31 | T_FILE, 32 | T_SYMLINK 33 | }; 34 | 35 | struct attr { 36 | uint32_t type; 37 | unsigned int atime; 38 | unsigned int mtime; 39 | unsigned int ctime; 40 | unsigned int size; 41 | }; 42 | }; 43 | 44 | inline unmarshall & 45 | operator>>(unmarshall &u, extent_protocol::attr &a) 46 | { 47 | u >> a.type; 48 | u >> a.atime; 49 | u >> a.mtime; 50 | u >> a.ctime; 51 | u >> a.size; 52 | return u; 53 | } 54 | 55 | inline marshall & 56 | operator<<(marshall &m, extent_protocol::attr a) 57 | { 58 | m << a.type; 59 | m << a.atime; 60 | m << a.mtime; 61 | m << a.ctime; 62 | m << a.size; 63 | return m; 64 | } 65 | 66 | #endif -------------------------------------------------------------------------------- /yfs/extent_server.cc: -------------------------------------------------------------------------------- 1 | // the extent server implementation 2 | 3 | #include "extent_server.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | extent_server::extent_server() 13 | { 14 | im = new inode_manager(); 15 | } 16 | 17 | int extent_server::create(uint32_t type, extent_protocol::extentid_t &id) 18 | { 19 | // alloc a new inode and return inum 20 | printf("extent_server: create inode\n"); 21 | id = im->alloc_inode(type); 22 | 23 | return extent_protocol::OK; 24 | } 25 | 26 | int extent_server::put(extent_protocol::extentid_t id, std::string buf, int &) 27 | { 28 | id &= 0x7fffffff; 29 | 30 | const char * cbuf = buf.c_str(); 31 | int size = buf.size(); 32 | im->write_file(id, cbuf, size); 33 | 34 | return extent_protocol::OK; 35 | } 36 | 37 | int extent_server::get(extent_protocol::extentid_t id, std::string &buf) 38 | { 39 | printf("extent_server: get %lld\n", id); 40 | 41 | id &= 0x7fffffff; 42 | 43 | int size = 0; 44 | char *cbuf = NULL; 45 | 46 | im->read_file(id, &cbuf, &size); 47 | if (size == 0) 48 | buf = ""; 49 | else { 50 | buf.assign(cbuf, size); 51 | free(cbuf); 52 | } 53 | 54 | return extent_protocol::OK; 55 | } 56 | 57 | int extent_server::getattr(extent_protocol::extentid_t id, extent_protocol::attr &a) 58 | { 59 | printf("extent_server: getattr %lld\n", id); 60 | 61 | id &= 0x7fffffff; 62 | 63 | extent_protocol::attr attr; 64 | memset(&attr, 0, sizeof(attr)); 65 | im->getattr(id, attr); 66 | a = attr; 67 | 68 | return extent_protocol::OK; 69 | } 70 | 71 | int extent_server::remove(extent_protocol::extentid_t id, int &) 72 | { 73 | printf("extent_server: write %lld\n", id); 74 | 75 | id &= 0x7fffffff; 76 | im->remove_file(id); 77 | 78 | return extent_protocol::OK; 79 | } 80 | 81 | int extent_server::append_block(extent_protocol::extentid_t id, blockid_t &bid) 82 | { 83 | id &= 0x7fffffff; 84 | 85 | im->append_block(id, bid); 86 | 87 | return extent_protocol::OK; 88 | } 89 | 90 | int extent_server::get_block_ids(extent_protocol::extentid_t id, std::list &block_ids) 91 | { 92 | id &= 0x7fffffff; 93 | 94 | im->get_block_ids(id, block_ids); 95 | 96 | return extent_protocol::OK; 97 | } 98 | 99 | int extent_server::read_block(blockid_t id, std::string &buf) 100 | { 101 | char _buf[BLOCK_SIZE]; 102 | 103 | im->read_block(id, _buf); 104 | buf.assign(_buf, BLOCK_SIZE); 105 | 106 | return extent_protocol::OK; 107 | } 108 | 109 | int extent_server::write_block(blockid_t id, std::string buf, int &) 110 | { 111 | if (buf.size() != BLOCK_SIZE) 112 | return extent_protocol::IOERR; 113 | 114 | im->write_block(id, (const char *) buf.data()); 115 | 116 | return extent_protocol::OK; 117 | } 118 | 119 | int extent_server::complete(extent_protocol::extentid_t eid, uint32_t size, int &) 120 | { 121 | im->complete(eid, size); 122 | return extent_protocol::OK; 123 | } 124 | 125 | -------------------------------------------------------------------------------- /yfs/extent_server.h: -------------------------------------------------------------------------------- 1 | // this is the extent server 2 | 3 | #ifndef extent_server_h 4 | #define extent_server_h 5 | 6 | #include 7 | #include 8 | #include 9 | #include "extent_protocol.h" 10 | #include "inode_manager.h" 11 | 12 | class extent_server { 13 | protected: 14 | #if 0 15 | typedef struct extent { 16 | std::string data; 17 | struct extent_protocol::attr attr; 18 | } extent_t; 19 | std::map extents; 20 | #endif 21 | inode_manager *im; 22 | 23 | public: 24 | extent_server(); 25 | 26 | int create(uint32_t type, extent_protocol::extentid_t &id); 27 | int put(extent_protocol::extentid_t id, std::string, int &); 28 | int get(extent_protocol::extentid_t id, std::string &); 29 | int getattr(extent_protocol::extentid_t id, extent_protocol::attr &); 30 | int remove(extent_protocol::extentid_t id, int &); 31 | int get_block_ids(extent_protocol::extentid_t id, std::list &); 32 | int read_block(blockid_t id, std::string &buf); 33 | int write_block(blockid_t id, std::string buf, int &); 34 | int append_block(extent_protocol::extentid_t eid, blockid_t &bid); 35 | int complete(extent_protocol::extentid_t eid, uint32_t size, int &); 36 | }; 37 | 38 | #endif 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /yfs/extent_smain.cc: -------------------------------------------------------------------------------- 1 | #include "rpc.h" 2 | #include 3 | #include 4 | #include 5 | #include "extent_server.h" 6 | #include 7 | // Main loop of extent server 8 | 9 | int 10 | main(int argc, char *argv[]) 11 | { 12 | int count = 0; 13 | 14 | if(argc != 2){ 15 | fprintf(stderr, "Usage: %s port\n", argv[0]); 16 | exit(1); 17 | } 18 | 19 | setvbuf(stdout, NULL, _IONBF, 0); 20 | 21 | char *count_env = getenv("RPC_COUNT"); 22 | if(count_env != NULL){ 23 | count = atoi(count_env); 24 | } 25 | 26 | rpcs server(atoi(argv[1]), count); 27 | extent_server ls; 28 | 29 | server.reg(extent_protocol::get, &ls, &extent_server::get); 30 | server.reg(extent_protocol::getattr, &ls, &extent_server::getattr); 31 | server.reg(extent_protocol::put, &ls, &extent_server::put); 32 | server.reg(extent_protocol::remove, &ls, &extent_server::remove); 33 | server.reg(extent_protocol::create, &ls, &extent_server::create); 34 | server.reg(extent_protocol::get_block_ids, &ls, &extent_server::get_block_ids); 35 | server.reg(extent_protocol::read_block, &ls, &extent_server::read_block); 36 | server.reg(extent_protocol::write_block, &ls, &extent_server::write_block); 37 | server.reg(extent_protocol::append_block, &ls, &extent_server::append_block); 38 | server.reg(extent_protocol::complete, &ls, &extent_server::complete); 39 | 40 | while(1) 41 | sleep(1000); 42 | } -------------------------------------------------------------------------------- /yfs/gettime.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c), MM Weiss 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * 3. Neither the name of the MM Weiss nor the names of its contributors 16 | * may be used to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 22 | * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 24 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 26 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | /* 31 | * clock_gettime_stub.c 32 | * gcc -Wall -c clock_gettime_stub.c 33 | * posix realtime functions; MacOS user space glue 34 | */ 35 | 36 | /* @comment 37 | * other possible implementation using intel builtin rdtsc 38 | * rdtsc-workaround: http://www.mcs.anl.gov/~kazutomo/rdtsc.html 39 | * 40 | * we could get the ticks by doing this 41 | * 42 | * __asm __volatile("mov %%ebx, %%esi\n\t" 43 | * "cpuid\n\t" 44 | * "xchg %%esi, %%ebx\n\t" 45 | * "rdtsc" 46 | * : "=a" (a), 47 | * "=d" (d) 48 | * ); 49 | 50 | * we could even replace our tricky sched_yield call by assembly code to get a better accurency, 51 | * anyway the following C stub will satisfy 99% of apps using posix clock_gettime call, 52 | * moreover, the setter version (clock_settime) could be easly written using mach primitives: 53 | * http://www.opensource.apple.com/source/xnu/xnu-${VERSION}/osfmk/man/ (clock_[set|get]_time) 54 | * 55 | * hackers don't be crackers, don't you use a flush toilet? 56 | * 57 | * 58 | * @see draft: ./posix-realtime-stub/posix-realtime-stub.c 59 | * 60 | */ 61 | 62 | 63 | #ifdef __APPLE__ 64 | 65 | #pragma weak clock_gettime 66 | 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | 76 | typedef enum { 77 | CLOCK_REALTIME, 78 | CLOCK_MONOTONIC, 79 | CLOCK_PROCESS_CPUTIME_ID, 80 | CLOCK_THREAD_CPUTIME_ID 81 | } clockid_t; 82 | 83 | static mach_timebase_info_data_t __clock_gettime_inf; 84 | 85 | int clock_gettime(clockid_t clk_id, struct timespec *tp) { 86 | kern_return_t ret; 87 | clock_serv_t clk; 88 | clock_id_t clk_serv_id; 89 | mach_timespec_t tm; 90 | 91 | uint64_t start, end, delta, nano; 92 | 93 | task_basic_info_data_t tinfo; 94 | task_thread_times_info_data_t ttinfo; 95 | mach_msg_type_number_t tflag; 96 | 97 | int retval = -1; 98 | switch (clk_id) { 99 | case CLOCK_REALTIME: 100 | case CLOCK_MONOTONIC: 101 | clk_serv_id = clk_id == CLOCK_REALTIME ? CALENDAR_CLOCK : SYSTEM_CLOCK; 102 | if (KERN_SUCCESS == (ret = host_get_clock_service(mach_host_self(), clk_serv_id, &clk))) { 103 | if (KERN_SUCCESS == (ret = clock_get_time(clk, &tm))) { 104 | tp->tv_sec = tm.tv_sec; 105 | tp->tv_nsec = tm.tv_nsec; 106 | retval = 0; 107 | } 108 | } 109 | if (KERN_SUCCESS != ret) { 110 | errno = EINVAL; 111 | retval = -1; 112 | } 113 | break; 114 | case CLOCK_PROCESS_CPUTIME_ID: 115 | case CLOCK_THREAD_CPUTIME_ID: 116 | start = mach_absolute_time(); 117 | if (clk_id == CLOCK_PROCESS_CPUTIME_ID) { 118 | getpid(); 119 | } else { 120 | sched_yield(); 121 | } 122 | end = mach_absolute_time(); 123 | delta = end - start; 124 | if (0 == __clock_gettime_inf.denom) { 125 | mach_timebase_info(&__clock_gettime_inf); 126 | } 127 | nano = delta * __clock_gettime_inf.numer / __clock_gettime_inf.denom; 128 | tp->tv_sec = nano * 1e-9; 129 | tp->tv_nsec = nano - (tp->tv_sec * 1e9); 130 | retval = 0; 131 | break; 132 | default: 133 | errno = EINVAL; 134 | retval = -1; 135 | } 136 | return retval; 137 | } 138 | 139 | #endif // __APPLE__ 140 | -------------------------------------------------------------------------------- /yfs/gettime.h: -------------------------------------------------------------------------------- 1 | #ifndef gettime_h 2 | #define gettime_h 3 | 4 | #ifdef __APPLE__ 5 | typedef enum { 6 | CLOCK_REALTIME, 7 | CLOCK_MONOTONIC, 8 | CLOCK_PROCESS_CPUTIME_ID, 9 | CLOCK_THREAD_CPUTIME_ID 10 | } clockid_t; 11 | 12 | int clock_gettime(clockid_t clk_id, struct timespec *tp); 13 | #endif 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /yfs/grade.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while [ $# -ne 0 ]; do 4 | case $1 in 5 | -q) 6 | QUIET=1 7 | ;; 8 | *) 9 | ;; 10 | esac 11 | shift 12 | done 13 | 14 | if [ "x$QUIET" != "x1" ]; then 15 | score=0 16 | exec 5>&1 17 | ./test-lab4-part0.sh 18 | if [ $? -eq 0 ]; then 19 | echo "Part 0 OK" 20 | else 21 | echo "Part 0 ERROR" 22 | fi 23 | part1=$(./test-lab4-part1.sh | tee /dev/fd/5 | grep -o -P "(?<=Part 1 score: )[0-9]+") 24 | score=$(($score + $part1)) 25 | part2=$(./test-lab4-part2.sh | tee /dev/fd/5 | grep -o -P "(?<=Part 2 score: )[0-9]+") 26 | score=$(($score + $part2)) 27 | part3=$(./test-lab4-part3.sh | tee /dev/fd/5 | grep -o -P "(?<=Part 3 score: )[0-9]+") 28 | score=$(($score + $part3)) 29 | echo "Score: $score/$((15 + 50 + 35))" 30 | else 31 | score=0 32 | part1=$(./test-lab4-part1.sh 2>/dev/null | grep -o -P "(?<=Part 1 score: )[0-9]+") 33 | score=$(($score + $part1)) 34 | part2=$(./test-lab4-part2.sh 2>/dev/null | grep -o -P "(?<=Part 2 score: )[0-9]+") 35 | score=$(($score + $part2)) 36 | part3=$(./test-lab4-part3.sh 2>/dev/null | grep -o -P "(?<=Part 3 score: )[0-9]+") 37 | score=$(($score + $part3)) 38 | echo $score 39 | fi 40 | -------------------------------------------------------------------------------- /yfs/handle.cc: -------------------------------------------------------------------------------- 1 | #include "handle.h" 2 | #include 3 | #include "tprintf.h" 4 | 5 | handle_mgr mgr; 6 | 7 | handle::handle(std::string m) 8 | { 9 | h = mgr.get_handle(m); 10 | } 11 | 12 | rpcc * 13 | handle::safebind() 14 | { 15 | if (!h) 16 | return NULL; 17 | ScopedLock ml(&h->cl_mutex); 18 | if (h->del) 19 | return NULL; 20 | if (h->cl) 21 | return h->cl; 22 | sockaddr_in dstsock; 23 | make_sockaddr(h->m.c_str(), &dstsock); 24 | rpcc *cl = new rpcc(dstsock); 25 | tprintf("handler_mgr::get_handle trying to bind...%s\n", h->m.c_str()); 26 | int ret; 27 | if (cl->islossy()) 28 | ret = cl->bind(); 29 | else 30 | ret = cl->bind(rpcc::to(1000)); 31 | if (ret < 0) { 32 | tprintf("handle_mgr::get_handle bind failure! %s %d\n", h->m.c_str(), ret); 33 | delete cl; 34 | h->del = true; 35 | } else { 36 | tprintf("handle_mgr::get_handle bind succeeded %s\n", h->m.c_str()); 37 | h->cl = cl; 38 | } 39 | return h->cl; 40 | } 41 | 42 | handle::~handle() 43 | { 44 | if (h) mgr.done_handle(h); 45 | } 46 | 47 | handle_mgr::handle_mgr() 48 | { 49 | VERIFY (pthread_mutex_init(&handle_mutex, NULL) == 0); 50 | } 51 | 52 | struct hinfo * 53 | handle_mgr::get_handle(std::string m) 54 | { 55 | ScopedLock ml(&handle_mutex); 56 | struct hinfo *h = 0; 57 | if (hmap.find(m) == hmap.end()) { 58 | h = new hinfo; 59 | h->cl = NULL; 60 | h->del = false; 61 | h->refcnt = 1; 62 | h->m = m; 63 | pthread_mutex_init(&h->cl_mutex, NULL); 64 | hmap[m] = h; 65 | } else if (!hmap[m]->del) { 66 | h = hmap[m]; 67 | h->refcnt ++; 68 | } 69 | return h; 70 | } 71 | 72 | void 73 | handle_mgr::done_handle(struct hinfo *h) 74 | { 75 | ScopedLock ml(&handle_mutex); 76 | h->refcnt--; 77 | if (h->refcnt == 0 && h->del) 78 | delete_handle_wo(h->m); 79 | } 80 | 81 | void 82 | handle_mgr::delete_handle(std::string m) 83 | { 84 | ScopedLock ml(&handle_mutex); 85 | delete_handle_wo(m); 86 | } 87 | 88 | // Must be called with handle_mutex locked. 89 | void 90 | handle_mgr::delete_handle_wo(std::string m) 91 | { 92 | if (hmap.find(m) == hmap.end()) { 93 | tprintf("handle_mgr::delete_handle_wo: cl %s isn't in cl list\n", m.c_str()); 94 | } else { 95 | tprintf("handle_mgr::delete_handle_wo: cl %s refcnt %d\n", m.c_str(), 96 | hmap[m]->refcnt); 97 | struct hinfo *h = hmap[m]; 98 | if (h->refcnt == 0) { 99 | if (h->cl) { 100 | h->cl->cancel(); 101 | delete h->cl; 102 | } 103 | pthread_mutex_destroy(&h->cl_mutex); 104 | hmap.erase(m); 105 | delete h; 106 | } else { 107 | h->del = true; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /yfs/handle.h: -------------------------------------------------------------------------------- 1 | // manage a cache of RPC connections. 2 | // assuming cid is a std::string holding the 3 | // host:port of the RPC server you want 4 | // to talk to: 5 | // 6 | // handle h(cid); 7 | // rpcc *cl = h.safebind(); 8 | // if(cl){ 9 | // ret = cl->call(...); 10 | // } else { 11 | // bind() failed 12 | // } 13 | // 14 | // if the calling program has not contacted 15 | // cid before, safebind() will create a new 16 | // connection, call bind(), and return 17 | // an rpcc*, or 0 if bind() failed. if the 18 | // program has previously contacted cid, 19 | // safebind() just returns the previously 20 | // created rpcc*. best not to hold any 21 | // mutexes while calling safebind(). 22 | 23 | #ifndef handle_h 24 | #define handle_h 25 | 26 | #include 27 | #include 28 | #include "rpc.h" 29 | 30 | struct hinfo { 31 | rpcc *cl; 32 | int refcnt; 33 | bool del; 34 | std::string m; 35 | pthread_mutex_t cl_mutex; 36 | }; 37 | 38 | class handle { 39 | private: 40 | struct hinfo *h; 41 | public: 42 | handle(std::string m); 43 | ~handle(); 44 | /* safebind will try to bind with the rpc server on the first call. 45 | * Since bind may block, the caller probably should not hold a mutex 46 | * when calling safebind. 47 | * 48 | * return: 49 | * if the first safebind succeeded, all later calls would return 50 | * a rpcc object; otherwise, all later calls would return NULL. 51 | * 52 | * Example: 53 | * handle h(dst); 54 | * XXX_protocol::status ret; 55 | * if (h.safebind()) { 56 | * ret = h.safebind()->call(...); 57 | * } 58 | * if (!h.safebind() || ret != XXX_protocol::OK) { 59 | * // handle failure 60 | * } 61 | */ 62 | rpcc *safebind(); 63 | }; 64 | 65 | class handle_mgr { 66 | private: 67 | pthread_mutex_t handle_mutex; 68 | std::map hmap; 69 | public: 70 | handle_mgr(); 71 | struct hinfo *get_handle(std::string m); 72 | void done_handle(struct hinfo *h); 73 | void delete_handle(std::string m); 74 | void delete_handle_wo(std::string m); 75 | }; 76 | 77 | extern class handle_mgr mgr; 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /yfs/hrpc.h: -------------------------------------------------------------------------------- 1 | #ifndef HRPC_H_ 2 | #define HRPC_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | template 9 | size_t GetDelimitedLength(const T &message) { 10 | size_t length = message.ByteSize(); 11 | return length + google::protobuf::io::CodedOutputStream::VarintSize64(length); 12 | } 13 | 14 | template 15 | bool HrpcWrite(int fd, const T1 &a1) { 16 | google::protobuf::io::FileOutputStream fos(fd); 17 | google::protobuf::io::CodedOutputStream cos(&fos); 18 | uint32_t len = GetDelimitedLength(a1); 19 | len = htonl(len); 20 | cos.WriteRaw(&len, sizeof(len)); 21 | cos.WriteVarint32(a1.ByteSize()); 22 | a1.SerializeWithCachedSizes(&cos); 23 | cos.Trim(); 24 | return !cos.HadError(); 25 | } 26 | 27 | template 28 | bool HrpcWrite(int fd, const T1 &a1, const T2 &a2) { 29 | google::protobuf::io::FileOutputStream fos(fd); 30 | google::protobuf::io::CodedOutputStream cos(&fos); 31 | uint32_t len = GetDelimitedLength(a1); 32 | len += GetDelimitedLength(a2); 33 | len = htonl(len); 34 | cos.WriteRaw(&len, sizeof(len)); 35 | cos.WriteVarint32(a1.ByteSize()); 36 | a1.SerializeWithCachedSizes(&cos); 37 | cos.WriteVarint32(a2.ByteSize()); 38 | a2.SerializeWithCachedSizes(&cos); 39 | cos.Trim(); 40 | return !cos.HadError(); 41 | } 42 | 43 | template 44 | bool HrpcWrite(int fd, const T1 &a1, const T2 &a2, const T3 &a3) { 45 | google::protobuf::io::FileOutputStream fos(fd); 46 | google::protobuf::io::CodedOutputStream cos(&fos); 47 | uint32_t len = GetDelimitedLength(a1); 48 | len += GetDelimitedLength(a2); 49 | len += GetDelimitedLength(a3); 50 | len = htonl(len); 51 | cos.WriteRaw(&len, sizeof(len)); 52 | cos.WriteVarint32(a1.ByteSize()); 53 | a1.SerializeWithCachedSizes(&cos); 54 | cos.WriteVarint32(a2.ByteSize()); 55 | a2.SerializeWithCachedSizes(&cos); 56 | cos.WriteVarint32(a3.ByteSize()); 57 | a3.SerializeWithCachedSizes(&cos); 58 | cos.Trim(); 59 | return !cos.HadError(); 60 | } 61 | 62 | static int ReadVariant(const uint8_t **p, const uint8_t *pend, uint64_t *v) { 63 | int shift = 0; 64 | uint64_t res = 0; 65 | while (*p != pend && **p >= 0x80) { 66 | res |= (((**p) & 0x7f) << shift); 67 | shift += 7; 68 | (*p)++; 69 | } 70 | if (*p == pend) 71 | return -1; 72 | res |= (((**p) & 0x7f) << shift); 73 | (*p)++; 74 | *v = res; 75 | return 0; 76 | } 77 | 78 | template 79 | int ReadDelimited(const uint8_t **p, const uint8_t *pend, T &t) { 80 | uint64_t len; 81 | if (ReadVariant(p, pend, &len) != 0) 82 | return -1; 83 | if (*p + len > pend) 84 | return -1; 85 | if (!t.ParseFromArray(*p, len)) 86 | return -1; 87 | (*p) += len; 88 | return 0; 89 | } 90 | 91 | template 92 | int ReadDelimited(std::string &buf, T &t) { 93 | uint64_t len; 94 | const uint8_t *p = (const uint8_t *) buf.data(), *pend = (const uint8_t *) buf.data() + buf.size(); 95 | if (ReadVariant(&p, pend, &len) != 0) 96 | return -1; 97 | if (p + len > pend) 98 | return -1; 99 | if (!t.ParseFromArray(p, len)) 100 | return -1; 101 | buf = buf.substr(p - (const uint8_t *) buf.data() + len); 102 | return 0; 103 | } 104 | 105 | bool HrpcRead(int fd, std::string &a1) { 106 | uint32_t len; 107 | ssize_t ret; 108 | if (read(fd, &len, sizeof(len)) != sizeof(len)) 109 | return false; 110 | len = ntohl(len); 111 | 112 | a1.resize(len); 113 | if ((ret = read(fd, (void *) a1.data(), len)) != len) 114 | return false; 115 | 116 | return true; 117 | } 118 | 119 | template 120 | bool HrpcRead(int fd, T1 &a1, std::string &a2) { 121 | if (!HrpcRead(fd, a2)) 122 | return false; 123 | 124 | if (ReadDelimited(a2, a1) != 0) 125 | return false; 126 | return true; 127 | } 128 | 129 | template 130 | bool HrpcRead(int fd, T1 &a1, T2 &a2, std::string &a3) { 131 | if (!HrpcRead(fd, a1, a3)) 132 | return false; 133 | 134 | if (ReadDelimited(a3, a2) != 0) 135 | return false; 136 | return true; 137 | } 138 | 139 | static __attribute__((used)) 140 | bool Connect(const std::string &ip, short port, 141 | std::unique_ptr &pfis, 142 | std::unique_ptr &pfos) { 143 | int fd = socket(AF_INET, SOCK_STREAM, 0); 144 | if (fd == -1) 145 | return false; 146 | sockaddr_in addr; 147 | memset(&addr, 0, sizeof(addr)); 148 | addr.sin_family = AF_INET; 149 | if (inet_aton(ip.c_str(), &addr.sin_addr) == 0) { 150 | close(fd); 151 | return false; 152 | } 153 | addr.sin_port = htons(port); 154 | if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) { 155 | close(fd); 156 | return false; 157 | } 158 | pfis.reset(new google::protobuf::io::FileInputStream(fd)); 159 | pfos.reset(new google::protobuf::io::FileOutputStream(fd)); 160 | pfos->SetCloseOnDelete(true); 161 | return true; 162 | } 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /yfs/inode_manager.h: -------------------------------------------------------------------------------- 1 | // inode layer interface. 2 | 3 | #ifndef inode_h 4 | #define inode_h 5 | 6 | #include 7 | #include "extent_protocol.h" // TODO: delete it 8 | 9 | #define DISK_SIZE 1024*1024*32 10 | #define BLOCK_SIZE (1024*16) 11 | #define BLOCK_NUM (DISK_SIZE/BLOCK_SIZE) 12 | 13 | // disk layer ----------------------------------------- 14 | 15 | class disk { 16 | private: 17 | unsigned char blocks[BLOCK_NUM][BLOCK_SIZE]; //1--->1 Byte 18 | 19 | public: 20 | disk(); 21 | void read_block(uint32_t id, char *buf); 22 | void write_block(uint32_t id, const char *buf); 23 | }; 24 | 25 | // block layer ----------------------------------------- 26 | 27 | typedef struct superblock { 28 | uint32_t size; 29 | uint32_t nblocks; 30 | uint32_t ninodes; 31 | } superblock_t; 32 | 33 | class block_manager { 34 | private: 35 | disk *d; 36 | std::map using_blocks; 37 | public: 38 | block_manager(); 39 | struct superblock sb; 40 | 41 | uint32_t alloc_block(); 42 | void free_block(uint32_t id); 43 | void read_block(uint32_t id, char *buf); 44 | void write_block(uint32_t id, const char *buf); 45 | }; 46 | 47 | // inode layer ----------------------------------------- 48 | 49 | #define INODE_NUM 1024 50 | 51 | // Inodes per block. 52 | #define IPB 1 53 | //(BLOCK_SIZE / sizeof(struct inode)) 54 | 55 | // Block containing inode i 56 | #define IBLOCK(i, nblocks) ((nblocks)/BPB + (i)/IPB + 3) 57 | 58 | // Bitmap bits per block 59 | #define BPB (BLOCK_SIZE*8) 60 | 61 | // Block containing bit for block b 62 | #define BBLOCK(b) ((b)/BPB + 2) 63 | 64 | #define NDIRECT 100 65 | #define NINDIRECT (BLOCK_SIZE / sizeof(uint)) 66 | #define MAXFILE (NDIRECT + NINDIRECT) 67 | 68 | typedef struct inode { 69 | short type; 70 | unsigned int size; 71 | unsigned int atime; 72 | unsigned int mtime; 73 | unsigned int ctime; 74 | blockid_t blocks[NDIRECT+1]; // Data block addresses 75 | } inode_t; 76 | 77 | class inode_manager { 78 | private: 79 | block_manager *bm; 80 | struct inode* get_inode(uint32_t inum); 81 | void put_inode(uint32_t inum, struct inode *ino); 82 | 83 | public: 84 | inode_manager(); 85 | uint32_t alloc_inode(uint32_t type); 86 | void free_inode(uint32_t inum); 87 | void read_file(uint32_t inum, char **buf, int *size); 88 | void write_file(uint32_t inum, const char *buf, int size); 89 | void remove_file(uint32_t inum); 90 | void getattr(uint32_t inum, extent_protocol::attr &a); 91 | void append_block(uint32_t inum, blockid_t &bid); 92 | void get_block_ids(uint32_t inum, std::list &block_ids); 93 | void read_block(blockid_t bid, char block[BLOCK_SIZE]); 94 | void write_block(blockid_t bid, const char block[BLOCK_SIZE]); 95 | void complete(uint32_t inum, uint32_t size); 96 | }; 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /yfs/lab4.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CaranthirLjh/FileSystem-yfs/0e2a77e2a33aa7fc749cd31b960ae00d757a6c35/yfs/lab4.tgz -------------------------------------------------------------------------------- /yfs/lang/algorithm.h: -------------------------------------------------------------------------------- 1 | // compile time version of min and max 2 | 3 | #ifndef algorithm_h 4 | #define algorithm_h 5 | 6 | template 7 | struct static_max 8 | { 9 | static const int value = A > B ? A : B; 10 | }; 11 | 12 | template 13 | struct static_min 14 | { 15 | static const int value = A < B ? A : B; 16 | }; 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /yfs/lang/verify.h: -------------------------------------------------------------------------------- 1 | // safe assertions. 2 | 3 | #ifndef verify_client_h 4 | #define verify_client_h 5 | 6 | #include 7 | #include 8 | 9 | #ifdef NDEBUG 10 | #define VERIFY(expr) do { if (!(expr)) abort(); } while (0) 11 | #else 12 | #define VERIFY(expr) assert(expr) 13 | #endif 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /yfs/lock_client.cc: -------------------------------------------------------------------------------- 1 | // RPC stubs for clients to talk to lock_server 2 | 3 | #include "lock_client.h" 4 | #include "rpc.h" 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | lock_client::lock_client(std::string dst) 12 | { 13 | sockaddr_in dstsock; 14 | make_sockaddr(dst.c_str(), &dstsock); 15 | cl = new rpcc(dstsock); 16 | if (cl->bind() < 0) { 17 | printf("lock_client: call bind\n"); 18 | } 19 | } 20 | 21 | int 22 | lock_client::stat(lock_protocol::lockid_t lid) 23 | { 24 | int r; 25 | lock_protocol::status ret = cl->call(lock_protocol::stat, cl->id(), lid, r); 26 | VERIFY (ret == lock_protocol::OK); 27 | return r; 28 | } 29 | 30 | lock_protocol::status 31 | lock_client::acquire(lock_protocol::lockid_t lid) 32 | { 33 | // Your lab2 part2 code goes here 34 | int r; 35 | lock_protocol::status ret = cl->call(lock_protocol::acquire, cl->id(), lid, r); 36 | VERIFY (ret == lock_protocol::OK); 37 | return r; 38 | } 39 | 40 | lock_protocol::status 41 | lock_client::release(lock_protocol::lockid_t lid) 42 | { 43 | // Your lab2 part2 code goes here 44 | int r; 45 | lock_protocol::status ret = cl->call(lock_protocol::release, cl->id(), lid, r); 46 | VERIFY (ret == lock_protocol::OK); 47 | return r; 48 | } -------------------------------------------------------------------------------- /yfs/lock_client.h: -------------------------------------------------------------------------------- 1 | // lock client interface. 2 | 3 | #ifndef lock_client_h 4 | #define lock_client_h 5 | 6 | #include 7 | #include "lock_protocol.h" 8 | #include "rpc.h" 9 | #include 10 | 11 | // Client interface to the lock server 12 | class lock_client { 13 | protected: 14 | rpcc *cl; 15 | public: 16 | lock_client(std::string d); 17 | virtual ~lock_client() {}; 18 | virtual lock_protocol::status acquire(lock_protocol::lockid_t); 19 | virtual lock_protocol::status release(lock_protocol::lockid_t); 20 | virtual lock_protocol::status stat(lock_protocol::lockid_t); 21 | }; 22 | 23 | 24 | #endif -------------------------------------------------------------------------------- /yfs/lock_client_cache.h: -------------------------------------------------------------------------------- 1 | // lock client interface. 2 | 3 | #ifndef lock_client_cache_h 4 | 5 | #define lock_client_cache_h 6 | 7 | #include 8 | #include "lock_protocol.h" 9 | #include "rpc.h" 10 | #include "lock_client.h" 11 | #include "lang/verify.h" 12 | 13 | //client state 14 | enum client_state { 15 | NONE, 16 | FREE, 17 | LOCKED, 18 | ACQUIRING, 19 | RELEASING 20 | }; 21 | 22 | //the property of lock in client 23 | struct lock_property{ 24 | public: 25 | //struct function 26 | lock_property(){}; 27 | ~lock_property(){}; 28 | //properties 29 | client_state state; 30 | pthread_mutex_t mutex_lock; 31 | pthread_cond_t cond_lock; 32 | bool revoke; 33 | bool retry; 34 | }; 35 | 36 | // Classes that inherit lock_release_user can override dorelease so that 37 | // that they will be called when lock_client releases a lock. 38 | // You will not need to do anything with this class until Lab 6. 39 | class lock_release_user { 40 | public: 41 | virtual void dorelease(lock_protocol::lockid_t) = 0; 42 | virtual ~lock_release_user() {}; 43 | }; 44 | 45 | class lock_client_cache : public lock_client { 46 | private: 47 | class lock_release_user *lu; 48 | int rlock_port; 49 | std::string hostname; 50 | std::string id; 51 | 52 | 53 | 54 | //client lock 55 | pthread_mutex_t client_mlock; 56 | pthread_cond_t client_clock; 57 | 58 | //lock map 59 | std::map lock_map; 60 | 61 | public: 62 | static int last_port; 63 | lock_client_cache(std::string xdst, class lock_release_user *l = 0); 64 | virtual ~lock_client_cache() {}; 65 | lock_protocol::status acquire(lock_protocol::lockid_t); 66 | lock_protocol::status release(lock_protocol::lockid_t); 67 | rlock_protocol::status revoke_handler(lock_protocol::lockid_t, 68 | int &); 69 | rlock_protocol::status retry_handler(lock_protocol::lockid_t, 70 | int &); 71 | }; 72 | 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /yfs/lock_demo.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Lock demo 3 | // 4 | 5 | #include "lock_protocol.h" 6 | #include "lock_client.h" 7 | #include "rpc.h" 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | std::string dst; 14 | lock_client *lc; 15 | 16 | int 17 | main(int argc, char *argv[]) 18 | { 19 | int r; 20 | 21 | if(argc != 2){ 22 | fprintf(stderr, "Usage: %s [host:]port\n", argv[0]); 23 | exit(1); 24 | } 25 | 26 | dst = argv[1]; 27 | lc = new lock_client(dst); 28 | r = lc->stat(1); 29 | printf ("stat returned %d\n", r); 30 | } 31 | -------------------------------------------------------------------------------- /yfs/lock_protocol.h: -------------------------------------------------------------------------------- 1 | // lock protocol 2 | 3 | #ifndef lock_protocol_h 4 | #define lock_protocol_h 5 | 6 | #include "rpc.h" 7 | 8 | class lock_protocol { 9 | public: 10 | enum xxstatus { OK, RETRY, RPCERR, NOENT, IOERR }; 11 | typedef int status; 12 | typedef unsigned long long lockid_t; 13 | enum rpc_numbers { 14 | acquire = 0x7001, 15 | release, 16 | stat 17 | }; 18 | }; 19 | 20 | class rlock_protocol { 21 | public: 22 | enum xxstatus { OK, RPCERR, REVOKE }; 23 | typedef int status; 24 | enum rpc_numbers { 25 | revoke = 0x8001, 26 | retry = 0x8002 27 | }; 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /yfs/lock_server.cc: -------------------------------------------------------------------------------- 1 | // the lock server implementation 2 | 3 | #include "lock_server.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | lock_server::lock_server(): 10 | nacquire (0) 11 | { 12 | pthread_mutex_init(&server_mlock,NULL); 13 | pthread_cond_init(&server_conlock,NULL); 14 | } 15 | 16 | lock_protocol::status 17 | lock_server::stat(int clt, lock_protocol::lockid_t lid, int &r) 18 | { 19 | lock_protocol::status ret = lock_protocol::OK; 20 | printf("stat request from clt %d\n", clt); 21 | r = nacquire; 22 | return ret; 23 | } 24 | 25 | lock_protocol::status 26 | lock_server::acquire(int clt, lock_protocol::lockid_t lid, int &r) 27 | { 28 | lock_protocol::status ret = lock_protocol::OK; 29 | // Your lab2 part2 code goes here 30 | std::cout<<"lock_server::acquire(beginconfig):"<<"clt:"< 8 | #include "lock_protocol.h" 9 | #include "lock_client.h" 10 | #include "rpc.h" 11 | 12 | struct lock_config{ 13 | //lock_protocol::lockid_t lock_Id;//lock id 14 | bool lock_status;//lock status:True=Onlock False=Unlock 15 | int lock_owner;//lock owner:the clt which own the lock 16 | }; 17 | 18 | class lock_server { 19 | 20 | protected: 21 | int nacquire; 22 | 23 | //map of lock:lockId-lockConfig 24 | std::map lock_map; 25 | 26 | pthread_mutex_t server_mlock;//add mutex 27 | pthread_cond_t server_conlock;//add conditional variable 28 | 29 | public: 30 | lock_server(); 31 | ~lock_server() {}; 32 | lock_protocol::status stat(int clt, lock_protocol::lockid_t lid, int &); 33 | lock_protocol::status acquire(int clt, lock_protocol::lockid_t lid, int &); 34 | lock_protocol::status release(int clt, lock_protocol::lockid_t lid, int &); 35 | }; 36 | 37 | #endif -------------------------------------------------------------------------------- /yfs/lock_server_cache.h: -------------------------------------------------------------------------------- 1 | #ifndef lock_server_cache_h 2 | #define lock_server_cache_h 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include "lock_protocol.h" 9 | #include "rpc.h" 10 | #include "lock_server.h" 11 | 12 | //the property of lock in server 13 | struct lock_property{ 14 | public: 15 | //struct function 16 | lock_property(){}; 17 | ~lock_property(){}; 18 | //properties 19 | bool state; 20 | pthread_mutex_t mutex_lock; 21 | pthread_cond_t cond_lock; 22 | std::string owner; 23 | std::set wait_list; 24 | bool revoke; 25 | }; 26 | 27 | 28 | class lock_server_cache { 29 | private: 30 | int nacquire; 31 | 32 | //lock of the lock map 33 | pthread_mutex_t lock_map_mlock; 34 | //lock map 35 | std::map lock_map; 36 | 37 | public: 38 | lock_server_cache(); 39 | lock_protocol::status stat(lock_protocol::lockid_t, int &); 40 | int acquire(lock_protocol::lockid_t, std::string id, int &); 41 | int release(lock_protocol::lockid_t, std::string id, int &); 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /yfs/lock_smain.cc: -------------------------------------------------------------------------------- 1 | #include "rpc.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | //#include "lock_server.h" 7 | #include "lock_server_cache.h" 8 | 9 | #include "jsl_log.h" 10 | 11 | // Main loop of lock_server 12 | 13 | int 14 | main(int argc, char *argv[]) 15 | { 16 | int count = 0; 17 | 18 | setvbuf(stdout, NULL, _IONBF, 0); 19 | setvbuf(stderr, NULL, _IONBF, 0); 20 | 21 | srandom(getpid()); 22 | 23 | if(argc != 2){ 24 | fprintf(stderr, "Usage: %s port\n", argv[0]); 25 | exit(1); 26 | } 27 | 28 | char *count_env = getenv("RPC_COUNT"); 29 | if(count_env != NULL){ 30 | count = atoi(count_env); 31 | } 32 | 33 | //jsl_set_debug(2); 34 | 35 | #ifndef RSM 36 | lock_server_cache ls; 37 | rpcs server(atoi(argv[1]), count); 38 | server.reg(lock_protocol::stat, &ls, &lock_server_cache::stat); 39 | server.reg(lock_protocol::release, &ls, &lock_server_cache::release); 40 | server.reg(lock_protocol::acquire, &ls, &lock_server_cache::acquire); 41 | #endif 42 | 43 | 44 | while(1) 45 | sleep(1000); 46 | } -------------------------------------------------------------------------------- /yfs/namenode.h: -------------------------------------------------------------------------------- 1 | #ifndef NAMENODE_H_ 2 | #define NAMENODE_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "yfs_client.h" 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | class extent_client; 15 | class lock_client; 16 | class yfs_client; 17 | 18 | class HdfsException : public std::runtime_error { 19 | public: 20 | HdfsException() : runtime_error("") {} 21 | HdfsException(const char *what) : runtime_error(what) {} 22 | }; 23 | 24 | bool operator<(const DatanodeIDProto &, const DatanodeIDProto &); 25 | bool operator==(const DatanodeIDProto &, const DatanodeIDProto &); 26 | 27 | class NameNode { 28 | struct LocatedBlock { 29 | blockid_t block_id; 30 | uint64_t offset, size; 31 | std::list locs; 32 | LocatedBlock(blockid_t block_id, 33 | uint64_t offset, 34 | uint64_t size, 35 | const DatanodeIDProto &loc) : 36 | block_id(block_id), 37 | offset(offset), 38 | size(size), 39 | locs(1, loc) {} 40 | LocatedBlock(blockid_t block_id, 41 | uint64_t offset, 42 | uint64_t size, 43 | const std::list &locs) : 44 | block_id(block_id), 45 | offset(offset), 46 | size(size), 47 | locs(locs) {} 48 | }; 49 | 50 | private: 51 | extent_client *ec; 52 | lock_client_cache *lc; 53 | yfs_client *yfs; 54 | DatanodeIDProto master_datanode; 55 | std::map pendingWrite; 56 | 57 | /* Add your member variables/functions here */ 58 | std::set HDFS_block; 59 | std::map datanode; 60 | //heart beat: 61 | unsigned long long heartbeat_count; 62 | void SendHeartbeat(); 63 | static string inum2str(yfs_client::inum); 64 | 65 | 66 | private: 67 | void GetFileInfo(); 68 | bool RecursiveLookup(const std::string &path, yfs_client::inum &ino, yfs_client::inum &last); 69 | bool RecursiveLookup(const std::string &path, yfs_client::inum &ino); 70 | bool RecursiveLookupParent(const std::string &path, yfs_client::inum &ino); 71 | bool RecursiveDelete(yfs_client::inum ino); 72 | bool ConvertLocatedBlock(const LocatedBlock &src, LocatedBlockProto &dst); 73 | std::list GetBlockLocations(yfs_client::inum ino); 74 | bool Complete(yfs_client::inum ino, uint32_t new_size); 75 | LocatedBlock AppendBlock(yfs_client::inum ino); 76 | bool Rename(yfs_client::inum src_dir_ino, std::string src_name, yfs_client::inum dst_dir_ino, std::string dst_name); 77 | bool Mkdir(yfs_client::inum parent, std::string name, mode_t mode, yfs_client::inum &ino_out); 78 | bool Create(yfs_client::inum parent, std::string name, mode_t mode, yfs_client::inum &ino_out); 79 | bool Isfile(yfs_client::inum ino); 80 | bool Isdir(yfs_client::inum ino); 81 | bool Readlink(yfs_client::inum ino, std::string &dest); 82 | bool Getfile(yfs_client::inum, yfs_client::fileinfo &); 83 | bool Getdir(yfs_client::inum, yfs_client::dirinfo &); 84 | void DualLock(lock_protocol::lockid_t a, lock_protocol::lockid_t b); 85 | void DualUnlock(lock_protocol::lockid_t a, lock_protocol::lockid_t b); 86 | bool Readdir(yfs_client::inum, std::list &); 87 | bool Unlink(yfs_client::inum parent, std::string name, yfs_client::inum ino); 88 | static void *_RegisterDatanode(void *arg); 89 | void RegisterDatanode(DatanodeIDProto id); 90 | void DatanodeHeartbeat(DatanodeIDProto id); 91 | std::list GetDatanodes(); 92 | static bool ReplicateBlock(blockid_t bid, DatanodeIDProto from, DatanodeIDProto to); 93 | public: 94 | void init(const std::string &extent_dst, const std::string &lock_dst); 95 | bool PBGetFileInfoFromInum(yfs_client::inum ino, HdfsFileStatusProto &info); 96 | void PBGetFileInfo(const GetFileInfoRequestProto &req, GetFileInfoResponseProto &resp); 97 | void PBGetListing(const GetListingRequestProto &req, GetListingResponseProto &resp); 98 | void PBGetBlockLocations(const GetBlockLocationsRequestProto &req, GetBlockLocationsResponseProto &resp); 99 | void PBRegisterDatanode(const RegisterDatanodeRequestProto &req, RegisterDatanodeResponseProto &resp); 100 | void PBGetServerDefaults(const GetServerDefaultsRequestProto &req, GetServerDefaultsResponseProto &resp); 101 | void PBCreate(const CreateRequestProto &req, CreateResponseProto &resp); 102 | void PBComplete(const CompleteRequestProto &req, CompleteResponseProto &resp); 103 | void PBAddBlock(const AddBlockRequestProto &req, AddBlockResponseProto &resp); 104 | void PBRenewLease(const RenewLeaseRequestProto &req, RenewLeaseResponseProto &resp); 105 | void PBRename(const RenameRequestProto &req, RenameResponseProto &resp); 106 | void PBDelete(const DeleteRequestProto &req, DeleteResponseProto &resp); 107 | void PBMkdirs(const MkdirsRequestProto &req, MkdirsResponseProto &resp); 108 | void PBGetFsStats(const GetFsStatsRequestProto &req, GetFsStatsResponseProto &resp); 109 | void PBSetSafeMode(const SetSafeModeRequestProto &req, SetSafeModeResponseProto &resp); 110 | void PBGetDatanodeReport(const GetDatanodeReportRequestProto &req, GetDatanodeReportResponseProto &resp); 111 | void PBDatanodeHeartbeat(const DatanodeHeartbeatRequestProto &req, DatanodeHeartbeatResponseProto &resp); 112 | }; 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /yfs/part2_tester.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | score=0 4 | 5 | mkdir yfs1 >/dev/null 2>&1 6 | 7 | ./start.sh 8 | 9 | test_if_has_mount(){ 10 | mount | grep -q "yfs_client" 11 | if [ $? -ne 0 ]; 12 | then 13 | echo "FATAL: Your YFS client has failed to mount its filesystem!" 14 | exit 15 | fi; 16 | } 17 | test_if_has_mount 18 | 19 | ################################################## 20 | 21 | # run test 1 22 | ./test-lab1-part2-a.pl yfs1 | grep -q "Passed all" 23 | if [ $? -ne 0 ]; 24 | then 25 | echo "Failed test-A" 26 | #exit 27 | else 28 | 29 | ps -e | grep -q "yfs_client" 30 | if [ $? -ne 0 ]; 31 | then 32 | echo "FATAL: yfs_client DIED!" 33 | exit 34 | else 35 | score=$((score+20)) 36 | #echo $score 37 | echo "Passed A" 38 | fi 39 | 40 | fi 41 | test_if_has_mount 42 | 43 | ################################################## 44 | 45 | ./test-lab1-part2-b.pl yfs1 | grep -q "Passed all" 46 | if [ $? -ne 0 ]; 47 | then 48 | echo "Failed test-B" 49 | #exit 50 | else 51 | 52 | ps -e | grep -q "yfs_client" 53 | if [ $? -ne 0 ]; 54 | then 55 | echo "FATAL: yfs_client DIED!" 56 | exit 57 | else 58 | score=$((score+20)) 59 | #echo $score 60 | echo "Passed B" 61 | fi 62 | 63 | fi 64 | test_if_has_mount 65 | 66 | ################################################## 67 | 68 | ./test-lab1-part2-c.pl yfs1 | grep -q "Passed all" 69 | if [ $? -ne 0 ]; 70 | then 71 | echo "Failed test-c" 72 | #exit 73 | else 74 | 75 | ps -e | grep -q "yfs_client" 76 | if [ $? -ne 0 ]; 77 | then 78 | echo "FATAL: yfs_client DIED!" 79 | exit 80 | else 81 | score=$((score+20)) 82 | #echo $score 83 | echo "Passed C" 84 | fi 85 | 86 | fi 87 | test_if_has_mount 88 | 89 | ################################################## 90 | 91 | 92 | ./test-lab1-part2-d.sh yfs1 | grep -q "Passed SYMLINK" 93 | if [ $? -ne 0 ]; 94 | then 95 | echo "Failed test-d" 96 | #exit 97 | else 98 | 99 | ps -e | grep -q "yfs_client" 100 | if [ $? -ne 0 ]; 101 | then 102 | echo "FATAL: yfs_client DIED!" 103 | exit 104 | else 105 | score=$((score+20)) 106 | echo "Passed D" 107 | #echo $score 108 | fi 109 | 110 | fi 111 | test_if_has_mount 112 | 113 | ################################################################################## 114 | 115 | ./test-lab1-part2-e.sh yfs1 | grep -q "Passed BLOB" 116 | if [ $? -ne 0 ]; 117 | then 118 | echo "Failed test-e" 119 | else 120 | #exit 121 | ps -e | grep -q "yfs_client" 122 | if [ $? -ne 0 ]; 123 | then 124 | echo "FATAL: yfs_client DIED!" 125 | exit 126 | else 127 | score=$((score+20)) 128 | echo "Passed E" 129 | #echo $score 130 | fi 131 | fi 132 | 133 | test_if_has_mount 134 | 135 | ################################################################################## 136 | robust(){ 137 | ./test-lab1-part2-f.sh yfs1 | grep -q "Passed ROBUSTNESS test" 138 | if [ $? -ne 0 ]; 139 | then 140 | echo "Failed test-f" 141 | else 142 | #exit 143 | ps -e | grep -q "yfs_client" 144 | if [ $? -ne 0 ]; 145 | then 146 | echo "FATAL: yfs_client DIED!" 147 | exit 148 | else 149 | score=$((score+20)) 150 | echo "Passed F -- Robustness" 151 | #echo $score 152 | fi 153 | fi 154 | 155 | test_if_has_mount 156 | } 157 | 158 | # finally reaches here! 159 | #echo "Passed all tests!" 160 | 161 | ./stop.sh 162 | echo "" 163 | echo "Part2 score: "$score"/100" 164 | -------------------------------------------------------------------------------- /yfs/proto/datanode.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | import "common.proto"; 4 | 5 | message CachingStrategyProto { 6 | optional bool dropBehind = 1; 7 | optional int64 readahead = 2; 8 | } 9 | 10 | message OpReadBlockProto { 11 | required ClientOperationHeaderProto header = 1; 12 | required uint64 offset = 2; 13 | required uint64 len = 3; 14 | optional bool sendChecksums = 4 [default = true]; 15 | optional CachingStrategyProto cachingStrategy = 5; 16 | } 17 | 18 | message PacketHeaderProto { 19 | // All fields must be fixed-length! 20 | required sfixed64 offsetInBlock = 1; 21 | required sfixed64 seqno = 2; 22 | required bool lastPacketInBlock = 3; 23 | required sfixed32 dataLen = 4; 24 | optional bool syncBlock = 5 [default = false]; 25 | } 26 | 27 | message OpWriteBlockProto { 28 | required ClientOperationHeaderProto header = 1; 29 | repeated DatanodeInfoProto targets = 2; 30 | optional DatanodeInfoProto source = 3; 31 | enum BlockConstructionStage { 32 | PIPELINE_SETUP_APPEND = 0; 33 | // pipeline set up for failed PIPELINE_SETUP_APPEND recovery 34 | PIPELINE_SETUP_APPEND_RECOVERY = 1; 35 | // data streaming 36 | DATA_STREAMING = 2; 37 | // pipeline setup for failed data streaming recovery 38 | PIPELINE_SETUP_STREAMING_RECOVERY = 3; 39 | // close the block and pipeline 40 | PIPELINE_CLOSE = 4; 41 | // Recover a failed PIPELINE_CLOSE 42 | PIPELINE_CLOSE_RECOVERY = 5; 43 | // pipeline set up for block creation 44 | PIPELINE_SETUP_CREATE = 6; 45 | // transfer RBW for adding datanodes 46 | TRANSFER_RBW = 7; 47 | // transfer Finalized for adding datanodes 48 | TRANSFER_FINALIZED = 8; 49 | } 50 | required BlockConstructionStage stage = 4; 51 | required uint32 pipelineSize = 5; 52 | required uint64 minBytesRcvd = 6; 53 | required uint64 maxBytesRcvd = 7; 54 | required uint64 latestGenerationStamp = 8; 55 | 56 | /** 57 | * The requested checksum mechanism for this block write. 58 | */ 59 | required ChecksumProto requestedChecksum = 9; 60 | optional CachingStrategyProto cachingStrategy = 10; 61 | optional StorageTypeProto storageType = 11 [default = DISK]; 62 | repeated StorageTypeProto targetStorageTypes = 12; 63 | 64 | /** 65 | * Hint to the DataNode that the block can be allocated on transient 66 | * storage i.e. memory and written to disk lazily. The DataNode is free 67 | * to ignore this hint. 68 | */ 69 | optional bool allowLazyPersist = 13 [default = false]; 70 | //whether to pin the block, so Balancer won't move it. 71 | optional bool pinning = 14 [default = false]; 72 | repeated bool targetPinnings = 15; 73 | } 74 | 75 | message PipelineAckProto { 76 | required sint64 seqno = 1; 77 | repeated Status reply = 2; 78 | optional uint64 downstreamAckTimeNanos = 3 [default = 0]; 79 | repeated uint32 flag = 4 [packed=true]; 80 | } 81 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/any.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | #ifndef GOOGLE_PROTOBUF_ANY_H__ 32 | #define GOOGLE_PROTOBUF_ANY_H__ 33 | 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | namespace google { 42 | namespace protobuf { 43 | namespace internal { 44 | 45 | // Helper class used to implement google::protobuf::Any. 46 | class LIBPROTOBUF_EXPORT AnyMetadata { 47 | typedef ArenaStringPtr UrlType; 48 | typedef ArenaStringPtr ValueType; 49 | public: 50 | // AnyMetadata does not take ownership of "type_url" and "value". 51 | AnyMetadata(UrlType* type_url, ValueType* value); 52 | 53 | // Packs a message using the default type URL prefix: "type.googleapis.com". 54 | // The resulted type URL will be "type.googleapis.com/". 55 | void PackFrom(const Message& message); 56 | // Packs a message using the given type URL prefix. The type URL will be 57 | // constructed by concatenating the message type's full name to the prefix 58 | // with an optional "/" separator if the prefix doesn't already end up "/". 59 | // For example, both PackFrom(message, "type.googleapis.com") and 60 | // PackFrom(message, "type.googleapis.com/") yield the same result type 61 | // URL: "type.googleapis.com/". 62 | void PackFrom(const Message& message, const string& type_url_prefix); 63 | 64 | // Unpacks the payload into the given message. Returns false if the message's 65 | // type doesn't match the type specified in the type URL (i.e., the full 66 | // name after the last "/" of the type URL doesn't match the message's actaul 67 | // full name) or parsing the payload has failed. 68 | bool UnpackTo(Message* message) const; 69 | 70 | // Checks whether the type specified in the type URL matches the given type. 71 | // A type is consdiered matching if its full name matches the full name after 72 | // the last "/" in the type URL. 73 | template 74 | bool Is() const { 75 | return InternalIs(T::default_instance().GetDescriptor()); 76 | } 77 | 78 | private: 79 | bool InternalIs(const Descriptor* message) const; 80 | 81 | UrlType* type_url_; 82 | ValueType* value_; 83 | 84 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AnyMetadata); 85 | }; 86 | 87 | extern const char kAnyFullTypeName[]; // "google.protobuf.Any". 88 | extern const char kTypeGoogleApisComPrefix[]; // "type.googleapis.com/". 89 | extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/". 90 | 91 | // Get the proto type name from Any::type_url value. For example, passing 92 | // "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in 93 | // *full_type_name. Returns false if type_url does not start with 94 | // "type.googleapis.com" or "type.googleprod.com". 95 | bool ParseAnyTypeUrl(const string& type_url, string* full_type_name); 96 | 97 | // See if message is of type google.protobuf.Any, if so, return the descriptors 98 | // for "type_url" and "value" fields. 99 | bool GetAnyFieldDescriptors(const Message& message, 100 | const FieldDescriptor** type_url_field, 101 | const FieldDescriptor** value_field); 102 | 103 | } // namespace internal 104 | } // namespace protobuf 105 | 106 | } // namespace google 107 | #endif // GOOGLE_PROTOBUF_ANY_H__ 108 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/duration.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option go_package = "github.com/golang/protobuf/ptypes/duration"; 37 | option java_package = "com.google.protobuf"; 38 | option java_outer_classname = "DurationProto"; 39 | option java_multiple_files = true; 40 | option java_generate_equals_and_hash = true; 41 | option objc_class_prefix = "GPB"; 42 | 43 | // A Duration represents a signed, fixed-length span of time represented 44 | // as a count of seconds and fractions of seconds at nanosecond 45 | // resolution. It is independent of any calendar and concepts like "day" 46 | // or "month". It is related to Timestamp in that the difference between 47 | // two Timestamp values is a Duration and it can be added or subtracted 48 | // from a Timestamp. Range is approximately +-10,000 years. 49 | // 50 | // Example 1: Compute Duration from two Timestamps in pseudo code. 51 | // 52 | // Timestamp start = ...; 53 | // Timestamp end = ...; 54 | // Duration duration = ...; 55 | // 56 | // duration.seconds = end.seconds - start.seconds; 57 | // duration.nanos = end.nanos - start.nanos; 58 | // 59 | // if (duration.seconds < 0 && duration.nanos > 0) { 60 | // duration.seconds += 1; 61 | // duration.nanos -= 1000000000; 62 | // } else if (durations.seconds > 0 && duration.nanos < 0) { 63 | // duration.seconds -= 1; 64 | // duration.nanos += 1000000000; 65 | // } 66 | // 67 | // Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. 68 | // 69 | // Timestamp start = ...; 70 | // Duration duration = ...; 71 | // Timestamp end = ...; 72 | // 73 | // end.seconds = start.seconds + duration.seconds; 74 | // end.nanos = start.nanos + duration.nanos; 75 | // 76 | // if (end.nanos < 0) { 77 | // end.seconds -= 1; 78 | // end.nanos += 1000000000; 79 | // } else if (end.nanos >= 1000000000) { 80 | // end.seconds += 1; 81 | // end.nanos -= 1000000000; 82 | // } 83 | // 84 | // 85 | message Duration { 86 | 87 | // Signed seconds of the span of time. Must be from -315,576,000,000 88 | // to +315,576,000,000 inclusive. 89 | int64 seconds = 1; 90 | 91 | // Signed fractions of a second at nanosecond resolution of the span 92 | // of time. Durations less than one second are represented with a 0 93 | // `seconds` field and a positive or negative `nanos` field. For durations 94 | // of one second or more, a non-zero value for the `nanos` field must be 95 | // of the same sign as the `seconds` field. Must be from -999,999,999 96 | // to +999,999,999 inclusive. 97 | int32 nanos = 2; 98 | } 99 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/empty.pb.h: -------------------------------------------------------------------------------- 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! 2 | // source: google/protobuf/empty.proto 3 | 4 | #ifndef PROTOBUF_google_2fprotobuf_2fempty_2eproto__INCLUDED 5 | #define PROTOBUF_google_2fprotobuf_2fempty_2eproto__INCLUDED 6 | 7 | #include 8 | 9 | #include 10 | 11 | #if GOOGLE_PROTOBUF_VERSION < 3000000 12 | #error This file was generated by a newer version of protoc which is 13 | #error incompatible with your Protocol Buffer headers. Please update 14 | #error your headers. 15 | #endif 16 | #if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 17 | #error This file was generated by an older version of protoc which is 18 | #error incompatible with your Protocol Buffer headers. Please 19 | #error regenerate this file with a newer version of protoc. 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | // @@protoc_insertion_point(includes) 31 | 32 | namespace google { 33 | namespace protobuf { 34 | 35 | // Internal implementation detail -- do not call these. 36 | void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto(); 37 | void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto(); 38 | void protobuf_ShutdownFile_google_2fprotobuf_2fempty_2eproto(); 39 | 40 | class Empty; 41 | 42 | // =================================================================== 43 | 44 | class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Empty) */ { 45 | public: 46 | Empty(); 47 | virtual ~Empty(); 48 | 49 | Empty(const Empty& from); 50 | 51 | inline Empty& operator=(const Empty& from) { 52 | CopyFrom(from); 53 | return *this; 54 | } 55 | 56 | inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); } 57 | inline void* GetMaybeArenaPointer() const { 58 | return MaybeArenaPtr(); 59 | } 60 | static const ::google::protobuf::Descriptor* descriptor(); 61 | static const Empty& default_instance(); 62 | 63 | void UnsafeArenaSwap(Empty* other); 64 | void Swap(Empty* other); 65 | 66 | // implements Message ---------------------------------------------- 67 | 68 | inline Empty* New() const { return New(NULL); } 69 | 70 | Empty* New(::google::protobuf::Arena* arena) const; 71 | void CopyFrom(const ::google::protobuf::Message& from); 72 | void MergeFrom(const ::google::protobuf::Message& from); 73 | void CopyFrom(const Empty& from); 74 | void MergeFrom(const Empty& from); 75 | void Clear(); 76 | bool IsInitialized() const; 77 | 78 | int ByteSize() const; 79 | bool MergePartialFromCodedStream( 80 | ::google::protobuf::io::CodedInputStream* input); 81 | void SerializeWithCachedSizes( 82 | ::google::protobuf::io::CodedOutputStream* output) const; 83 | ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( 84 | bool deterministic, ::google::protobuf::uint8* output) const; 85 | ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { 86 | return InternalSerializeWithCachedSizesToArray(false, output); 87 | } 88 | int GetCachedSize() const { return _cached_size_; } 89 | private: 90 | void SharedCtor(); 91 | void SharedDtor(); 92 | void SetCachedSize(int size) const; 93 | void InternalSwap(Empty* other); 94 | protected: 95 | explicit Empty(::google::protobuf::Arena* arena); 96 | private: 97 | static void ArenaDtor(void* object); 98 | inline void RegisterArenaDtor(::google::protobuf::Arena* arena); 99 | private: 100 | inline ::google::protobuf::Arena* GetArenaNoVirtual() const { 101 | return _internal_metadata_.arena(); 102 | } 103 | inline void* MaybeArenaPtr() const { 104 | return _internal_metadata_.raw_arena_ptr(); 105 | } 106 | public: 107 | 108 | ::google::protobuf::Metadata GetMetadata() const; 109 | 110 | // nested types ---------------------------------------------------- 111 | 112 | // accessors ------------------------------------------------------- 113 | 114 | // @@protoc_insertion_point(class_scope:google.protobuf.Empty) 115 | private: 116 | 117 | ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; 118 | friend class ::google::protobuf::Arena; 119 | typedef void InternalArenaConstructable_; 120 | typedef void DestructorSkippable_; 121 | bool _is_default_instance_; 122 | mutable int _cached_size_; 123 | friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto(); 124 | friend void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto(); 125 | friend void protobuf_ShutdownFile_google_2fprotobuf_2fempty_2eproto(); 126 | 127 | void InitAsDefaultInstance(); 128 | static Empty* default_instance_; 129 | }; 130 | // =================================================================== 131 | 132 | 133 | // =================================================================== 134 | 135 | #if !PROTOBUF_INLINE_NOT_IN_HEADERS 136 | // Empty 137 | 138 | #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS 139 | 140 | // @@protoc_insertion_point(namespace_scope) 141 | 142 | } // namespace protobuf 143 | } // namespace google 144 | 145 | // @@protoc_insertion_point(global_scope) 146 | 147 | #endif // PROTOBUF_google_2fprotobuf_2fempty_2eproto__INCLUDED 148 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/empty.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option go_package = "github.com/golang/protobuf/ptypes/empty"; 37 | option java_package = "com.google.protobuf"; 38 | option java_outer_classname = "EmptyProto"; 39 | option java_multiple_files = true; 40 | option java_generate_equals_and_hash = true; 41 | option objc_class_prefix = "GPB"; 42 | option cc_enable_arenas = true; 43 | 44 | // A generic empty message that you can re-use to avoid defining duplicated 45 | // empty messages in your APIs. A typical example is to use it as the request 46 | // or the response type of an API method. For instance: 47 | // 48 | // service Foo { 49 | // rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); 50 | // } 51 | // 52 | // The JSON representation for `Empty` is empty JSON object `{}`. 53 | message Empty {} 54 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/generated_enum_reflection.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: jasonh@google.com (Jason Hsueh) 32 | // 33 | // This header is logically internal, but is made public because it is used 34 | // from protocol-compiler-generated code, which may reside in other components. 35 | // It provides reflection support for generated enums, and is included in 36 | // generated .pb.h files and should have minimal dependencies. The methods are 37 | // implemented in generated_message_reflection.cc. 38 | 39 | #ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ 40 | #define GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ 41 | 42 | #include 43 | 44 | #include 45 | #include 46 | 47 | namespace google { 48 | namespace protobuf { 49 | class EnumDescriptor; 50 | } // namespace protobuf 51 | 52 | namespace protobuf { 53 | 54 | // Returns the EnumDescriptor for enum type E, which must be a 55 | // proto-declared enum type. Code generated by the protocol compiler 56 | // will include specializations of this template for each enum type declared. 57 | template 58 | const EnumDescriptor* GetEnumDescriptor(); 59 | 60 | namespace internal { 61 | 62 | // Helper for EnumType_Parse functions: try to parse the string 'name' as an 63 | // enum name of the given type, returning true and filling in value on success, 64 | // or returning false and leaving value unchanged on failure. 65 | LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor, 66 | const string& name, 67 | int* value); 68 | 69 | template 70 | bool ParseNamedEnum(const EnumDescriptor* descriptor, 71 | const string& name, 72 | EnumType* value) { 73 | int tmp; 74 | if (!ParseNamedEnum(descriptor, name, &tmp)) return false; 75 | *value = static_cast(tmp); 76 | return true; 77 | } 78 | 79 | // Just a wrapper around printing the name of a value. The main point of this 80 | // function is not to be inlined, so that you can do this without including 81 | // descriptor.h. 82 | LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value); 83 | 84 | } // namespace internal 85 | } // namespace protobuf 86 | 87 | } // namespace google 88 | #endif // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ 89 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/generated_enum_util.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | #ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__ 32 | #define GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__ 33 | 34 | #include 35 | 36 | namespace google { 37 | namespace protobuf { 38 | 39 | // This type trait can be used to cause templates to only match proto2 enum 40 | // types. 41 | template struct is_proto_enum : ::google::protobuf::internal::false_type {}; 42 | 43 | } // namespace protobuf 44 | 45 | } // namespace google 46 | #endif // GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__ 47 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/generated_message_util.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | // Based on original Protocol Buffers design by 33 | // Sanjay Ghemawat, Jeff Dean, and others. 34 | // 35 | // This file contains miscellaneous helper code used by generated code -- 36 | // including lite types -- but which should not be used directly by users. 37 | 38 | #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ 39 | #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ 40 | 41 | #include 42 | #include 43 | 44 | #include 45 | #include 46 | 47 | namespace google { 48 | 49 | namespace protobuf { 50 | 51 | class Arena; 52 | namespace io { class CodedInputStream; } 53 | 54 | namespace internal { 55 | 56 | 57 | // Annotation for the compiler to emit a deprecation message if a field marked 58 | // with option 'deprecated=true' is used in the code, or for other things in 59 | // generated code which are deprecated. 60 | // 61 | // For internal use in the pb.cc files, deprecation warnings are suppressed 62 | // there. 63 | #undef DEPRECATED_PROTOBUF_FIELD 64 | #define PROTOBUF_DEPRECATED 65 | 66 | #define GOOGLE_PROTOBUF_DEPRECATED_ATTR 67 | 68 | 69 | // Constants for special floating point values. 70 | LIBPROTOBUF_EXPORT double Infinity(); 71 | LIBPROTOBUF_EXPORT double NaN(); 72 | 73 | // TODO(jieluo): Change to template. We have tried to use template, 74 | // but it causes net/rpc/python:rpcutil_test fail (the empty string will 75 | // init twice). It may related to swig. Change to template after we 76 | // found the solution. 77 | 78 | // Default empty string object. Don't use the pointer directly. Instead, call 79 | // GetEmptyString() to get the reference. 80 | LIBPROTOBUF_EXPORT extern const ::std::string* empty_string_; 81 | LIBPROTOBUF_EXPORT extern ProtobufOnceType empty_string_once_init_; 82 | LIBPROTOBUF_EXPORT void InitEmptyString(); 83 | 84 | 85 | LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyStringAlreadyInited() { 86 | assert(empty_string_ != NULL); 87 | return *empty_string_; 88 | } 89 | LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() { 90 | ::google::protobuf::GoogleOnceInit(&empty_string_once_init_, &InitEmptyString); 91 | return GetEmptyStringAlreadyInited(); 92 | } 93 | 94 | LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str); 95 | 96 | 97 | // True if IsInitialized() is true for all elements of t. Type is expected 98 | // to be a RepeatedPtrField. It's useful to have this 99 | // helper here to keep the protobuf compiler from ever having to emit loops in 100 | // IsInitialized() methods. We want the C++ compiler to inline this or not 101 | // as it sees fit. 102 | template bool AllAreInitialized(const Type& t) { 103 | for (int i = t.size(); --i >= 0; ) { 104 | if (!t.Get(i).IsInitialized()) return false; 105 | } 106 | return true; 107 | } 108 | 109 | class ArenaString; 110 | 111 | // Read a length (varint32), followed by a string, from *input. Return a 112 | // pointer to a copy of the string that resides in *arena. Requires both 113 | // args to be non-NULL. If something goes wrong while reading the data 114 | // then NULL is returned (e.g., input does not start with a valid varint). 115 | LIBPROTOBUF_EXPORT ArenaString* ReadArenaString( 116 | ::google::protobuf::io::CodedInputStream* input, 117 | ::google::protobuf::Arena* arena); 118 | 119 | // Helper function to crash on merge failure. 120 | // Moved out of generated code to reduce binary size. 121 | LIBPROTOBUF_EXPORT void MergeFromFail(const char* file, int line) GOOGLE_ATTRIBUTE_NORETURN; 122 | 123 | } // namespace internal 124 | } // namespace protobuf 125 | 126 | } // namespace google 127 | #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ 128 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/io/strtod.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // A locale-independent version of strtod(), used to parse floating 32 | // point default values in .proto files, where the decimal separator 33 | // is always a dot. 34 | 35 | #ifndef GOOGLE_PROTOBUF_IO_STRTOD_H__ 36 | #define GOOGLE_PROTOBUF_IO_STRTOD_H__ 37 | 38 | namespace google { 39 | namespace protobuf { 40 | namespace io { 41 | 42 | // A locale-independent version of the standard strtod(), which always 43 | // uses a dot as the decimal separator. 44 | double NoLocaleStrtod(const char* str, char** endptr); 45 | 46 | // Casts a double value to a float value. If the value is outside of the 47 | // representable range of float, it will be converted to positive or negative 48 | // infinity. 49 | float SafeDoubleToFloat(double value); 50 | 51 | } // namespace io 52 | } // namespace protobuf 53 | 54 | } // namespace google 55 | #endif // GOOGLE_PROTOBUF_IO_STRTOD_H__ 56 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/reflection_ops.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | // Based on original Protocol Buffers design by 33 | // Sanjay Ghemawat, Jeff Dean, and others. 34 | // 35 | // This header is logically internal, but is made public because it is used 36 | // from protocol-compiler-generated code, which may reside in other components. 37 | 38 | #ifndef GOOGLE_PROTOBUF_REFLECTION_OPS_H__ 39 | #define GOOGLE_PROTOBUF_REFLECTION_OPS_H__ 40 | 41 | #include 42 | #include 43 | 44 | namespace google { 45 | namespace protobuf { 46 | namespace internal { 47 | 48 | // Basic operations that can be performed using reflection. 49 | // These can be used as a cheap way to implement the corresponding 50 | // methods of the Message interface, though they are likely to be 51 | // slower than implementations tailored for the specific message type. 52 | // 53 | // This class should stay limited to operations needed to implement 54 | // the Message interface. 55 | // 56 | // This class is really a namespace that contains only static methods. 57 | class LIBPROTOBUF_EXPORT ReflectionOps { 58 | public: 59 | static void Copy(const Message& from, Message* to); 60 | static void Merge(const Message& from, Message* to); 61 | static void Clear(Message* message); 62 | static bool IsInitialized(const Message& message); 63 | static void DiscardUnknownFields(Message* message); 64 | 65 | // Finds all unset required fields in the message and adds their full 66 | // paths (e.g. "foo.bar[5].baz") to *names. "prefix" will be attached to 67 | // the front of each name. 68 | static void FindInitializationErrors(const Message& message, 69 | const string& prefix, 70 | vector* errors); 71 | 72 | private: 73 | // All methods are static. No need to construct. 74 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionOps); 75 | }; 76 | 77 | } // namespace internal 78 | } // namespace protobuf 79 | 80 | } // namespace google 81 | #endif // GOOGLE_PROTOBUF_REFLECTION_OPS_H__ 82 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/source_context.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option java_package = "com.google.protobuf"; 37 | option java_outer_classname = "SourceContextProto"; 38 | option java_multiple_files = true; 39 | option java_generate_equals_and_hash = true; 40 | option objc_class_prefix = "GPB"; 41 | 42 | // `SourceContext` represents information about the source of a 43 | // protobuf element, like the file in which it is defined. 44 | message SourceContext { 45 | // The path-qualified name of the .proto file that contained the associated 46 | // protobuf element. For example: `"google/protobuf/source_context.proto"`. 47 | string file_name = 1; 48 | } 49 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/struct.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option go_package = "github.com/golang/protobuf/ptypes/struct;structpb"; 37 | option java_package = "com.google.protobuf"; 38 | option java_outer_classname = "StructProto"; 39 | option java_multiple_files = true; 40 | option java_generate_equals_and_hash = true; 41 | option objc_class_prefix = "GPB"; 42 | 43 | 44 | // `Struct` represents a structured data value, consisting of fields 45 | // which map to dynamically typed values. In some languages, `Struct` 46 | // might be supported by a native representation. For example, in 47 | // scripting languages like JS a struct is represented as an 48 | // object. The details of that representation are described together 49 | // with the proto support for the language. 50 | // 51 | // The JSON representation for `Struct` is JSON object. 52 | message Struct { 53 | // Unordered map of dynamically typed values. 54 | map fields = 1; 55 | } 56 | 57 | // `Value` represents a dynamically typed value which can be either 58 | // null, a number, a string, a boolean, a recursive struct value, or a 59 | // list of values. A producer of value is expected to set one of that 60 | // variants, absence of any variant indicates an error. 61 | // 62 | // The JSON representation for `Value` is JSON value. 63 | message Value { 64 | // The kind of value. 65 | oneof kind { 66 | // Represents a null value. 67 | NullValue null_value = 1; 68 | // Represents a double value. 69 | double number_value = 2; 70 | // Represents a string value. 71 | string string_value = 3; 72 | // Represents a boolean value. 73 | bool bool_value = 4; 74 | // Represents a structured value. 75 | Struct struct_value = 5; 76 | // Represents a repeated `Value`. 77 | ListValue list_value = 6; 78 | } 79 | } 80 | 81 | // `NullValue` is a singleton enumeration to represent the null value for the 82 | // `Value` type union. 83 | // 84 | // The JSON representation for `NullValue` is JSON `null`. 85 | enum NullValue { 86 | // Null value. 87 | NULL_VALUE = 0; 88 | } 89 | 90 | // `ListValue` is a wrapper around a repeated field of values. 91 | // 92 | // The JSON representation for `ListValue` is JSON array. 93 | message ListValue { 94 | // Repeated field of dynamically typed values. 95 | repeated Value values = 1; 96 | } 97 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/stubs/atomic_sequence_num.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2014 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | #ifndef GOOGLE_PROTOBUF_ATOMIC_SEQUENCE_NUM_H_ 31 | #define GOOGLE_PROTOBUF_ATOMIC_SEQUENCE_NUM_H_ 32 | 33 | #include 34 | 35 | namespace google { 36 | namespace protobuf { 37 | namespace internal { 38 | 39 | class SequenceNumber { 40 | public: 41 | SequenceNumber() : word_(0) {} 42 | 43 | AtomicWord GetNext() { 44 | return NoBarrier_AtomicIncrement(&word_, 1) - 1; 45 | } 46 | private: 47 | AtomicWord word_; 48 | }; 49 | 50 | } // namespace internal 51 | } // namespace protobuf 52 | } // namespace google 53 | 54 | #endif // GOOGLE_PROTOBUF_ATOMIC_SEQUENCE_NUM_H_ 55 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/stubs/atomicops_internals_s390_gcc.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // This file is an internal atomic implementation, use atomicops.h instead. 6 | 7 | #ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_S390_H_ 8 | #define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_S390_H_ 9 | 10 | namespace google { 11 | namespace protobuf { 12 | namespace internal { 13 | 14 | inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, 15 | Atomic32 old_value, 16 | Atomic32 new_value) { 17 | return (__sync_val_compare_and_swap(ptr, old_value, new_value)); 18 | } 19 | 20 | inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, 21 | Atomic32 new_value) { 22 | Atomic32 old_value; 23 | do { 24 | old_value = *ptr; 25 | } while (__sync_bool_compare_and_swap(ptr, old_value, new_value) == false); 26 | return old_value; 27 | } 28 | 29 | inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, 30 | Atomic32 increment) { 31 | return Barrier_AtomicIncrement(ptr, increment); 32 | } 33 | 34 | inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, 35 | Atomic32 increment) { 36 | return __sync_add_and_fetch(ptr, increment); 37 | } 38 | 39 | inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, 40 | Atomic32 old_value, Atomic32 new_value) { 41 | return NoBarrier_CompareAndSwap(ptr, old_value, new_value); 42 | } 43 | 44 | inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, 45 | Atomic32 old_value, Atomic32 new_value) { 46 | return NoBarrier_CompareAndSwap(ptr, old_value, new_value); 47 | } 48 | 49 | inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { 50 | *ptr = value; 51 | } 52 | 53 | inline void MemoryBarrier() { __sync_synchronize(); } 54 | 55 | inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { 56 | *ptr = value; 57 | MemoryBarrier(); 58 | } 59 | 60 | inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { 61 | MemoryBarrier(); 62 | *ptr = value; 63 | } 64 | 65 | inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { return *ptr; } 66 | 67 | inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { 68 | Atomic32 value = *ptr; 69 | MemoryBarrier(); 70 | return value; 71 | } 72 | 73 | inline Atomic32 Release_Load(volatile const Atomic32* ptr) { 74 | MemoryBarrier(); 75 | return *ptr; 76 | } 77 | 78 | #ifdef GOOGLE_PROTOBUF_ARCH_64_BIT 79 | inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, 80 | Atomic64 old_value, 81 | Atomic64 new_value) { 82 | return (__sync_val_compare_and_swap(ptr, old_value, new_value)); 83 | } 84 | 85 | inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, 86 | Atomic64 new_value) { 87 | Atomic64 old_value; 88 | do { 89 | old_value = *ptr; 90 | } while (__sync_bool_compare_and_swap(ptr, old_value, new_value) == false); 91 | return old_value; 92 | } 93 | 94 | inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, 95 | Atomic64 increment) { 96 | return Barrier_AtomicIncrement(ptr, increment); 97 | } 98 | 99 | inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, 100 | Atomic64 increment) { 101 | return __sync_add_and_fetch(ptr, increment); 102 | } 103 | 104 | 105 | inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, 106 | Atomic64 old_value, Atomic64 new_value) { 107 | return NoBarrier_CompareAndSwap(ptr, old_value, new_value); 108 | } 109 | 110 | inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, 111 | Atomic64 old_value, Atomic64 new_value) { 112 | return NoBarrier_CompareAndSwap(ptr, old_value, new_value); 113 | } 114 | 115 | inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { 116 | *ptr = value; 117 | } 118 | 119 | inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { 120 | *ptr = value; 121 | MemoryBarrier(); 122 | } 123 | 124 | inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { 125 | MemoryBarrier(); 126 | *ptr = value; 127 | } 128 | 129 | inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { return *ptr; } 130 | 131 | inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { 132 | Atomic64 value = *ptr; 133 | MemoryBarrier(); 134 | return value; 135 | } 136 | 137 | inline Atomic64 Release_Load(volatile const Atomic64* ptr) { 138 | MemoryBarrier(); 139 | return *ptr; 140 | } 141 | 142 | #endif 143 | 144 | } // namespace internal 145 | } // namespace protobuf 146 | } // namespace google 147 | 148 | #endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_S390_H_ 149 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/stubs/mutex.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #ifndef GOOGLE_PROTOBUF_STUBS_MUTEX_H_ 31 | #define GOOGLE_PROTOBUF_STUBS_MUTEX_H_ 32 | 33 | #ifdef GOOGLE_PROTOBUF_NO_THREADLOCAL 34 | #include 35 | #endif 36 | 37 | #include 38 | 39 | // =================================================================== 40 | // emulates google3/base/mutex.h 41 | namespace google { 42 | namespace protobuf { 43 | namespace internal { 44 | 45 | // A Mutex is a non-reentrant (aka non-recursive) mutex. At most one thread T 46 | // may hold a mutex at a given time. If T attempts to Lock() the same Mutex 47 | // while holding it, T will deadlock. 48 | class LIBPROTOBUF_EXPORT Mutex { 49 | public: 50 | // Create a Mutex that is not held by anybody. 51 | Mutex(); 52 | 53 | // Destructor 54 | ~Mutex(); 55 | 56 | // Block if necessary until this Mutex is free, then acquire it exclusively. 57 | void Lock(); 58 | 59 | // Release this Mutex. Caller must hold it exclusively. 60 | void Unlock(); 61 | 62 | // Crash if this Mutex is not held exclusively by this thread. 63 | // May fail to crash when it should; will never crash when it should not. 64 | void AssertHeld(); 65 | 66 | private: 67 | struct Internal; 68 | Internal* mInternal; 69 | 70 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex); 71 | }; 72 | 73 | // Undefine the macros to workaround the conflicts with Google internal 74 | // MutexLock implementation. 75 | // TODO(liujisi): Remove the undef once internal macros are removed. 76 | #undef MutexLock 77 | #undef ReaderMutexLock 78 | #undef WriterMutexLock 79 | #undef MutexLockMaybe 80 | 81 | // MutexLock(mu) acquires mu when constructed and releases it when destroyed. 82 | class LIBPROTOBUF_EXPORT MutexLock { 83 | public: 84 | explicit MutexLock(Mutex *mu) : mu_(mu) { this->mu_->Lock(); } 85 | ~MutexLock() { this->mu_->Unlock(); } 86 | private: 87 | Mutex *const mu_; 88 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLock); 89 | }; 90 | 91 | // TODO(kenton): Implement these? Hard to implement portably. 92 | typedef MutexLock ReaderMutexLock; 93 | typedef MutexLock WriterMutexLock; 94 | 95 | // MutexLockMaybe is like MutexLock, but is a no-op when mu is NULL. 96 | class LIBPROTOBUF_EXPORT MutexLockMaybe { 97 | public: 98 | explicit MutexLockMaybe(Mutex *mu) : 99 | mu_(mu) { if (this->mu_ != NULL) { this->mu_->Lock(); } } 100 | ~MutexLockMaybe() { if (this->mu_ != NULL) { this->mu_->Unlock(); } } 101 | private: 102 | Mutex *const mu_; 103 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe); 104 | }; 105 | 106 | #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) 107 | template 108 | class ThreadLocalStorage { 109 | public: 110 | ThreadLocalStorage() { 111 | pthread_key_create(&key_, &ThreadLocalStorage::Delete); 112 | } 113 | ~ThreadLocalStorage() { 114 | pthread_key_delete(key_); 115 | } 116 | T* Get() { 117 | T* result = static_cast(pthread_getspecific(key_)); 118 | if (result == NULL) { 119 | result = new T(); 120 | pthread_setspecific(key_, result); 121 | } 122 | return result; 123 | } 124 | private: 125 | static void Delete(void* value) { 126 | delete static_cast(value); 127 | } 128 | pthread_key_t key_; 129 | 130 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadLocalStorage); 131 | }; 132 | #endif 133 | 134 | } // namespace internal 135 | 136 | // We made these internal so that they would show up as such in the docs, 137 | // but we don't want to stick "internal::" in front of them everywhere. 138 | using internal::Mutex; 139 | using internal::MutexLock; 140 | using internal::ReaderMutexLock; 141 | using internal::WriterMutexLock; 142 | using internal::MutexLockMaybe; 143 | 144 | 145 | } // namespace protobuf 146 | } // namespace google 147 | 148 | #endif // GOOGLE_PROTOBUF_STUBS_MUTEX_H_ 149 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/stubs/platform_macros.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2012 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | #ifndef GOOGLE_PROTOBUF_PLATFORM_MACROS_H_ 32 | #define GOOGLE_PROTOBUF_PLATFORM_MACROS_H_ 33 | 34 | #define GOOGLE_PROTOBUF_PLATFORM_ERROR \ 35 | #error "Host platform was not detected as supported by protobuf" 36 | 37 | // Processor architecture detection. For more info on what's defined, see: 38 | // http://msdn.microsoft.com/en-us/library/b0084kay.aspx 39 | // http://www.agner.org/optimize/calling_conventions.pdf 40 | // or with gcc, run: "echo | gcc -E -dM -" 41 | #if defined(_M_X64) || defined(__x86_64__) 42 | #define GOOGLE_PROTOBUF_ARCH_X64 1 43 | #define GOOGLE_PROTOBUF_ARCH_64_BIT 1 44 | #elif defined(_M_IX86) || defined(__i386__) 45 | #define GOOGLE_PROTOBUF_ARCH_IA32 1 46 | #define GOOGLE_PROTOBUF_ARCH_32_BIT 1 47 | #elif defined(__QNX__) 48 | #define GOOGLE_PROTOBUF_ARCH_ARM_QNX 1 49 | #define GOOGLE_PROTOBUF_ARCH_32_BIT 1 50 | #elif defined(__ARMEL__) 51 | #define GOOGLE_PROTOBUF_ARCH_ARM 1 52 | #define GOOGLE_PROTOBUF_ARCH_32_BIT 1 53 | #elif defined(__aarch64__) 54 | #define GOOGLE_PROTOBUF_ARCH_AARCH64 1 55 | #define GOOGLE_PROTOBUF_ARCH_64_BIT 1 56 | #elif defined(__MIPSEL__) 57 | #if defined(__LP64__) 58 | #define GOOGLE_PROTOBUF_ARCH_MIPS64 1 59 | #define GOOGLE_PROTOBUF_ARCH_64_BIT 1 60 | #else 61 | #define GOOGLE_PROTOBUF_ARCH_MIPS 1 62 | #define GOOGLE_PROTOBUF_ARCH_32_BIT 1 63 | #endif 64 | #elif defined(__pnacl__) 65 | #define GOOGLE_PROTOBUF_ARCH_32_BIT 1 66 | #elif defined(sparc) 67 | #define GOOGLE_PROTOBUF_ARCH_SPARC 1 68 | #if defined(__sparc_v9__) || defined(__sparcv9) || defined(__arch64__) 69 | #define GOOGLE_PROTOBUF_ARCH_64_BIT 1 70 | #else 71 | #define GOOGLE_PROTOBUF_ARCH_32_BIT 1 72 | #endif 73 | #elif defined(_POWER) || defined(__powerpc64__) || defined(__PPC64__) 74 | #define GOOGLE_PROTOBUF_ARCH_POWER 1 75 | #define GOOGLE_PROTOBUF_ARCH_64_BIT 1 76 | #elif defined(__PPC__) 77 | #define GOOGLE_PROTOBUF_ARCH_PPC 1 78 | #define GOOGLE_PROTOBUF_ARCH_32_BIT 1 79 | #elif defined(__s390__) || defined(__s390x__) 80 | #define GOOGLE_PROTOBUF_ARCH_S390 1 81 | #if defined(__s390x__) 82 | #define GOOGLE_PROTOBUF_ARCH_64_BIT 1 83 | #else 84 | #define GOOGLE_PROTOBUF_ARCH_32_BIT 1 85 | #endif 86 | #elif defined(__GNUC__) 87 | # if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)) 88 | // We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h 89 | # elif defined(__clang__) 90 | # if !__has_extension(c_atomic) 91 | GOOGLE_PROTOBUF_PLATFORM_ERROR 92 | # endif 93 | // We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h 94 | # endif 95 | # if __LP64__ 96 | # define GOOGLE_PROTOBUF_ARCH_64_BIT 1 97 | # else 98 | # define GOOGLE_PROTOBUF_ARCH_32_BIT 1 99 | # endif 100 | #else 101 | GOOGLE_PROTOBUF_PLATFORM_ERROR 102 | #endif 103 | 104 | #if defined(__APPLE__) 105 | #define GOOGLE_PROTOBUF_OS_APPLE 106 | #include 107 | #if TARGET_OS_IPHONE 108 | #define GOOGLE_PROTOBUF_OS_IPHONE 109 | #endif 110 | #elif defined(__EMSCRIPTEN__) 111 | #define GOOGLE_PROTOBUF_OS_EMSCRIPTEN 112 | #elif defined(__native_client__) 113 | #define GOOGLE_PROTOBUF_OS_NACL 114 | #elif defined(sun) 115 | #define GOOGLE_PROTOBUF_OS_SOLARIS 116 | #elif defined(_AIX) 117 | #define GOOGLE_PROTOBUF_OS_AIX 118 | #elif defined(__ANDROID__) 119 | #define GOOGLE_PROTOBUF_OS_ANDROID 120 | #endif 121 | 122 | #undef GOOGLE_PROTOBUF_PLATFORM_ERROR 123 | 124 | #if defined(GOOGLE_PROTOBUF_OS_ANDROID) || defined(GOOGLE_PROTOBUF_OS_IPHONE) 125 | // Android ndk does not support the __thread keyword very well yet. Here 126 | // we use pthread_key_create()/pthread_getspecific()/... methods for 127 | // TLS support on android. 128 | // iOS also does not support the __thread keyword. 129 | #define GOOGLE_PROTOBUF_NO_THREADLOCAL 130 | #endif 131 | 132 | #endif // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_ 133 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/stubs/singleton.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2014 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | #ifndef GOOGLE_PROTOBUF_STUBS_SINGLETON_H__ 31 | #define GOOGLE_PROTOBUF_STUBS_SINGLETON_H__ 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | namespace google { 38 | namespace protobuf { 39 | namespace internal { 40 | template 41 | class Singleton { 42 | public: 43 | static T* get() { 44 | GoogleOnceInit(&once_, &Singleton::Init); 45 | return instance_; 46 | } 47 | static void ShutDown() { 48 | delete instance_; 49 | instance_ = NULL; 50 | } 51 | private: 52 | static void Init() { 53 | instance_ = new T(); 54 | } 55 | static ProtobufOnceType once_; 56 | static T* instance_; 57 | }; 58 | 59 | template 60 | ProtobufOnceType Singleton::once_; 61 | 62 | template 63 | T* Singleton::instance_ = NULL; 64 | } // namespace internal 65 | } // namespace protobuf 66 | } // namespace google 67 | 68 | #endif // GOOGLE_PROTOBUF_STUBS_SINGLETON_H__ 69 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/stubs/status.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | #ifndef GOOGLE_PROTOBUF_STUBS_STATUS_H_ 31 | #define GOOGLE_PROTOBUF_STUBS_STATUS_H_ 32 | 33 | #include 34 | #include 35 | 36 | #include 37 | #include 38 | 39 | namespace google { 40 | namespace protobuf { 41 | namespace util { 42 | namespace error { 43 | // These values must match error codes defined in google/rpc/code.proto. 44 | enum Code { 45 | OK = 0, 46 | CANCELLED = 1, 47 | UNKNOWN = 2, 48 | INVALID_ARGUMENT = 3, 49 | DEADLINE_EXCEEDED = 4, 50 | NOT_FOUND = 5, 51 | ALREADY_EXISTS = 6, 52 | PERMISSION_DENIED = 7, 53 | UNAUTHENTICATED = 16, 54 | RESOURCE_EXHAUSTED = 8, 55 | FAILED_PRECONDITION = 9, 56 | ABORTED = 10, 57 | OUT_OF_RANGE = 11, 58 | UNIMPLEMENTED = 12, 59 | INTERNAL = 13, 60 | UNAVAILABLE = 14, 61 | DATA_LOSS = 15, 62 | }; 63 | } // namespace error 64 | 65 | class LIBPROTOBUF_EXPORT Status { 66 | public: 67 | // Creates a "successful" status. 68 | Status(); 69 | 70 | // Create a status in the canonical error space with the specified 71 | // code, and error message. If "code == 0", error_message is 72 | // ignored and a Status object identical to Status::OK is 73 | // constructed. 74 | Status(error::Code error_code, StringPiece error_message); 75 | Status(const Status&); 76 | Status& operator=(const Status& x); 77 | ~Status() {} 78 | 79 | // Some pre-defined Status objects 80 | static const Status OK; // Identical to 0-arg constructor 81 | static const Status CANCELLED; 82 | static const Status UNKNOWN; 83 | 84 | // Accessor 85 | bool ok() const { 86 | return error_code_ == error::OK; 87 | } 88 | int error_code() const { 89 | return error_code_; 90 | } 91 | StringPiece error_message() const { 92 | return error_message_; 93 | } 94 | 95 | bool operator==(const Status& x) const; 96 | bool operator!=(const Status& x) const { 97 | return !operator==(x); 98 | } 99 | 100 | // Return a combination of the error code name and message. 101 | string ToString() const; 102 | 103 | private: 104 | error::Code error_code_; 105 | string error_message_; 106 | }; 107 | 108 | // Prints a human-readable representation of 'x' to 'os'. 109 | LIBPROTOBUF_EXPORT ostream& operator<<(ostream& os, const Status& x); 110 | 111 | #define EXPECT_OK(value) EXPECT_TRUE((value).ok()) 112 | 113 | } // namespace util 114 | } // namespace protobuf 115 | } // namespace google 116 | #endif // GOOGLE_PROTOBUF_STUBS_STATUS_H_ 117 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/stubs/template_util.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005 Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // ---- 31 | // Author: lar@google.com (Laramie Leavitt) 32 | // 33 | // Template metaprogramming utility functions. 34 | // 35 | // This code is compiled directly on many platforms, including client 36 | // platforms like Windows, Mac, and embedded systems. Before making 37 | // any changes here, make sure that you're not breaking any platforms. 38 | // 39 | // 40 | // The names chosen here reflect those used in tr1 and the boost::mpl 41 | // library, there are similar operations used in the Loki library as 42 | // well. I prefer the boost names for 2 reasons: 43 | // 1. I think that portions of the Boost libraries are more likely to 44 | // be included in the c++ standard. 45 | // 2. It is not impossible that some of the boost libraries will be 46 | // included in our own build in the future. 47 | // Both of these outcomes means that we may be able to directly replace 48 | // some of these with boost equivalents. 49 | // 50 | #ifndef GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_ 51 | #define GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_ 52 | 53 | namespace google { 54 | namespace protobuf { 55 | namespace internal { 56 | 57 | // Types small_ and big_ are guaranteed such that sizeof(small_) < 58 | // sizeof(big_) 59 | typedef char small_; 60 | 61 | struct big_ { 62 | char dummy[2]; 63 | }; 64 | 65 | // Identity metafunction. 66 | template 67 | struct identity_ { 68 | typedef T type; 69 | }; 70 | 71 | // integral_constant, defined in tr1, is a wrapper for an integer 72 | // value. We don't really need this generality; we could get away 73 | // with hardcoding the integer type to bool. We use the fully 74 | // general integer_constant for compatibility with tr1. 75 | 76 | template 77 | struct integral_constant { 78 | static const T value = v; 79 | typedef T value_type; 80 | typedef integral_constant type; 81 | }; 82 | 83 | template const T integral_constant::value; 84 | 85 | 86 | // Abbreviations: true_type and false_type are structs that represent boolean 87 | // true and false values. Also define the boost::mpl versions of those names, 88 | // true_ and false_. 89 | typedef integral_constant true_type; 90 | typedef integral_constant false_type; 91 | typedef true_type true_; 92 | typedef false_type false_; 93 | 94 | // if_ is a templatized conditional statement. 95 | // if_ is a compile time evaluation of cond. 96 | // if_<>::type contains A if cond is true, B otherwise. 97 | template 98 | struct if_{ 99 | typedef A type; 100 | }; 101 | 102 | template 103 | struct if_ { 104 | typedef B type; 105 | }; 106 | 107 | 108 | // type_equals_ is a template type comparator, similar to Loki IsSameType. 109 | // type_equals_::value is true iff "A" is the same type as "B". 110 | // 111 | // New code should prefer base::is_same, defined in base/type_traits.h. 112 | // It is functionally identical, but is_same is the standard spelling. 113 | template 114 | struct type_equals_ : public false_ { 115 | }; 116 | 117 | template 118 | struct type_equals_ : public true_ { 119 | }; 120 | 121 | // and_ is a template && operator. 122 | // and_::value evaluates "A::value && B::value". 123 | template 124 | struct and_ : public integral_constant { 125 | }; 126 | 127 | // or_ is a template || operator. 128 | // or_::value evaluates "A::value || B::value". 129 | template 130 | struct or_ : public integral_constant { 131 | }; 132 | 133 | 134 | } // namespace internal 135 | } // namespace protobuf 136 | } // namespace google 137 | 138 | #endif // GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_ 139 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/timestamp.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option cc_enable_arenas = true; 37 | option go_package = "github.com/golang/protobuf/ptypes/timestamp"; 38 | option java_package = "com.google.protobuf"; 39 | option java_outer_classname = "TimestampProto"; 40 | option java_multiple_files = true; 41 | option java_generate_equals_and_hash = true; 42 | option objc_class_prefix = "GPB"; 43 | 44 | // A Timestamp represents a point in time independent of any time zone 45 | // or calendar, represented as seconds and fractions of seconds at 46 | // nanosecond resolution in UTC Epoch time. It is encoded using the 47 | // Proleptic Gregorian Calendar which extends the Gregorian calendar 48 | // backwards to year one. It is encoded assuming all minutes are 60 49 | // seconds long, i.e. leap seconds are "smeared" so that no leap second 50 | // table is needed for interpretation. Range is from 51 | // 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. 52 | // By restricting to that range, we ensure that we can convert to 53 | // and from RFC 3339 date strings. 54 | // See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt). 55 | // 56 | // Example 1: Compute Timestamp from POSIX `time()`. 57 | // 58 | // Timestamp timestamp; 59 | // timestamp.set_seconds(time(NULL)); 60 | // timestamp.set_nanos(0); 61 | // 62 | // Example 2: Compute Timestamp from POSIX `gettimeofday()`. 63 | // 64 | // struct timeval tv; 65 | // gettimeofday(&tv, NULL); 66 | // 67 | // Timestamp timestamp; 68 | // timestamp.set_seconds(tv.tv_sec); 69 | // timestamp.set_nanos(tv.tv_usec * 1000); 70 | // 71 | // Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. 72 | // 73 | // FILETIME ft; 74 | // GetSystemTimeAsFileTime(&ft); 75 | // UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; 76 | // 77 | // // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z 78 | // // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. 79 | // Timestamp timestamp; 80 | // timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); 81 | // timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); 82 | // 83 | // Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. 84 | // 85 | // long millis = System.currentTimeMillis(); 86 | // 87 | // Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) 88 | // .setNanos((int) ((millis % 1000) * 1000000)).build(); 89 | // 90 | // 91 | // Example 5: Compute Timestamp from current time in Python. 92 | // 93 | // now = time.time() 94 | // seconds = int(now) 95 | // nanos = int((now - seconds) * 10**9) 96 | // timestamp = Timestamp(seconds=seconds, nanos=nanos) 97 | // 98 | // 99 | message Timestamp { 100 | 101 | // Represents seconds of UTC time since Unix epoch 102 | // 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to 103 | // 9999-12-31T23:59:59Z inclusive. 104 | int64 seconds = 1; 105 | 106 | // Non-negative fractions of a second at nanosecond resolution. Negative 107 | // second values with fractions must still have non-negative nanos values 108 | // that count forward in time. Must be from 0 to 999,999,999 109 | // inclusive. 110 | int32 nanos = 2; 111 | } 112 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/util/type_resolver.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | #ifndef GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__ 32 | #define GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__ 33 | 34 | #include 35 | 36 | #include 37 | #include 38 | 39 | 40 | namespace google { 41 | namespace protobuf { 42 | class Type; 43 | class Enum; 44 | } // namespace protobuf 45 | 46 | 47 | namespace protobuf { 48 | class DescriptorPool; 49 | namespace util { 50 | 51 | // Abstract interface for a type resovler. 52 | // 53 | // Implementations of this interface must be thread-safe. 54 | class LIBPROTOBUF_EXPORT TypeResolver { 55 | public: 56 | TypeResolver() {} 57 | virtual ~TypeResolver() {} 58 | 59 | // Resolves a type url for a message type. 60 | virtual util::Status ResolveMessageType( 61 | const string& type_url, google::protobuf::Type* message_type) = 0; 62 | 63 | // Resolves a type url for an enum type. 64 | virtual util::Status ResolveEnumType(const string& type_url, 65 | google::protobuf::Enum* enum_type) = 0; 66 | 67 | private: 68 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeResolver); 69 | }; 70 | 71 | } // namespace util 72 | } // namespace protobuf 73 | 74 | } // namespace google 75 | #endif // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_H__ 76 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/util/type_resolver_util.h: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | #ifndef GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__ 32 | #define GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__ 33 | 34 | #include 35 | 36 | #include 37 | namespace google { 38 | namespace protobuf { 39 | class DescriptorPool; 40 | namespace util { 41 | class TypeResolver; 42 | 43 | // Creates a TypeResolver that serves type information in the given descriptor 44 | // pool. Caller takes ownership of the returned TypeResolver. 45 | LIBPROTOBUF_EXPORT TypeResolver* NewTypeResolverForDescriptorPool( 46 | const string& url_prefix, const DescriptorPool* pool); 47 | 48 | } // namespace util 49 | } // namespace protobuf 50 | 51 | } // namespace google 52 | #endif // GOOGLE_PROTOBUF_UTIL_TYPE_RESOLVER_UTIL_H__ 53 | -------------------------------------------------------------------------------- /yfs/proto/output/google/protobuf/wrappers.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Wrappers for primitive (non-message) types. These types are useful 32 | // for embedding primitives in the `google.protobuf.Any` type and for places 33 | // where we need to distinguish between the absence of a primitive 34 | // typed field and its default value. 35 | 36 | syntax = "proto3"; 37 | 38 | package google.protobuf; 39 | 40 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 41 | option cc_enable_arenas = true; 42 | option go_package = "github.com/golang/protobuf/ptypes/wrappers"; 43 | option java_package = "com.google.protobuf"; 44 | option java_outer_classname = "WrappersProto"; 45 | option java_multiple_files = true; 46 | option java_generate_equals_and_hash = true; 47 | option objc_class_prefix = "GPB"; 48 | 49 | // Wrapper message for `double`. 50 | // 51 | // The JSON representation for `DoubleValue` is JSON number. 52 | message DoubleValue { 53 | // The double value. 54 | double value = 1; 55 | } 56 | 57 | // Wrapper message for `float`. 58 | // 59 | // The JSON representation for `FloatValue` is JSON number. 60 | message FloatValue { 61 | // The float value. 62 | float value = 1; 63 | } 64 | 65 | // Wrapper message for `int64`. 66 | // 67 | // The JSON representation for `Int64Value` is JSON string. 68 | message Int64Value { 69 | // The int64 value. 70 | int64 value = 1; 71 | } 72 | 73 | // Wrapper message for `uint64`. 74 | // 75 | // The JSON representation for `UInt64Value` is JSON string. 76 | message UInt64Value { 77 | // The uint64 value. 78 | uint64 value = 1; 79 | } 80 | 81 | // Wrapper message for `int32`. 82 | // 83 | // The JSON representation for `Int32Value` is JSON number. 84 | message Int32Value { 85 | // The int32 value. 86 | int32 value = 1; 87 | } 88 | 89 | // Wrapper message for `uint32`. 90 | // 91 | // The JSON representation for `UInt32Value` is JSON number. 92 | message UInt32Value { 93 | // The uint32 value. 94 | uint32 value = 1; 95 | } 96 | 97 | // Wrapper message for `bool`. 98 | // 99 | // The JSON representation for `BoolValue` is JSON `true` and `false`. 100 | message BoolValue { 101 | // The bool value. 102 | bool value = 1; 103 | } 104 | 105 | // Wrapper message for `string`. 106 | // 107 | // The JSON representation for `StringValue` is JSON string. 108 | message StringValue { 109 | // The string value. 110 | string value = 1; 111 | } 112 | 113 | // Wrapper message for `bytes`. 114 | // 115 | // The JSON representation for `BytesValue` is JSON string. 116 | message BytesValue { 117 | // The bytes value. 118 | bytes value = 1; 119 | } 120 | -------------------------------------------------------------------------------- /yfs/readme: -------------------------------------------------------------------------------- 1 | test 2 | -------------------------------------------------------------------------------- /yfs/rpc/connection.h: -------------------------------------------------------------------------------- 1 | #ifndef connection_h 2 | #define connection_h 1 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "pollmgr.h" 13 | 14 | class connection; 15 | 16 | class chanmgr { 17 | public: 18 | virtual bool got_pdu(connection *c, char *b, int sz) = 0; 19 | virtual ~chanmgr() {} 20 | }; 21 | 22 | class connection : public aio_callback { 23 | public: 24 | struct charbuf { 25 | charbuf(): buf(NULL), sz(0), solong(0) {} 26 | charbuf (char *b, int s) : buf(b), sz(s), solong(0){} 27 | char *buf; 28 | int sz; 29 | int solong; //amount of bytes written or read so far 30 | }; 31 | 32 | connection(chanmgr *m1, int f1, int lossytest=0); 33 | ~connection(); 34 | 35 | int channo() { return fd_; } 36 | bool isdead(); 37 | void closeconn(); 38 | 39 | bool send(char *b, int sz); 40 | void write_cb(int s); 41 | void read_cb(int s); 42 | 43 | void incref(); 44 | void decref(); 45 | int ref(); 46 | 47 | int compare(connection *another); 48 | private: 49 | 50 | bool readpdu(); 51 | bool writepdu(); 52 | 53 | chanmgr *mgr_; 54 | const int fd_; 55 | bool dead_; 56 | 57 | charbuf wpdu_; 58 | charbuf rpdu_; 59 | 60 | struct timeval create_time_; 61 | 62 | int waiters_; 63 | int refno_; 64 | const int lossy_; 65 | 66 | pthread_mutex_t m_; 67 | pthread_mutex_t ref_m_; 68 | pthread_cond_t send_complete_; 69 | pthread_cond_t send_wait_; 70 | }; 71 | 72 | class tcpsconn { 73 | public: 74 | tcpsconn(chanmgr *m1, int port, int lossytest=0); 75 | ~tcpsconn(); 76 | 77 | void accept_conn(); 78 | private: 79 | 80 | pthread_mutex_t m_; 81 | pthread_t th_; 82 | int pipe_[2]; 83 | 84 | int tcp_; //file desciptor for accepting connection 85 | chanmgr *mgr_; 86 | int lossy_; 87 | std::map conns_; 88 | 89 | void process_accept(); 90 | }; 91 | 92 | struct bundle { 93 | bundle(chanmgr *m, int s, int l):mgr(m),tcp(s),lossy(l) {} 94 | chanmgr *mgr; 95 | int tcp; 96 | int lossy; 97 | }; 98 | 99 | void start_accept_thread(chanmgr *mgr, int port, pthread_t *th, int *fd = NULL, int lossy=0); 100 | connection *connect_to_dst(const sockaddr_in &dst, chanmgr *mgr, int lossy=0); 101 | #endif 102 | -------------------------------------------------------------------------------- /yfs/rpc/fifo.h: -------------------------------------------------------------------------------- 1 | #ifndef fifo_h 2 | #define fifo_h 3 | 4 | // fifo template 5 | // blocks enq() and deq() when queue is FULL or EMPTY 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "slock.h" 13 | #include "lang/verify.h" 14 | 15 | template 16 | class fifo { 17 | public: 18 | fifo(int m=0); 19 | ~fifo(); 20 | bool enq(T, bool blocking=true); 21 | void deq(T *); 22 | bool size(); 23 | 24 | private: 25 | std::list q_; 26 | pthread_mutex_t m_; 27 | pthread_cond_t non_empty_c_; // q went non-empty 28 | pthread_cond_t has_space_c_; // q is not longer overfull 29 | unsigned int max_; //maximum capacity of the queue, block enq threads if exceeds this limit 30 | }; 31 | 32 | template 33 | fifo::fifo(int limit) : max_(limit) 34 | { 35 | VERIFY(pthread_mutex_init(&m_, 0) == 0); 36 | VERIFY(pthread_cond_init(&non_empty_c_, 0) == 0); 37 | VERIFY(pthread_cond_init(&has_space_c_, 0) == 0); 38 | } 39 | 40 | template 41 | fifo::~fifo() 42 | { 43 | //fifo is to be deleted only when no threads are using it! 44 | VERIFY(pthread_mutex_destroy(&m_)==0); 45 | VERIFY(pthread_cond_destroy(&non_empty_c_) == 0); 46 | VERIFY(pthread_cond_destroy(&has_space_c_) == 0); 47 | } 48 | 49 | template bool 50 | fifo::size() 51 | { 52 | ScopedLock ml(&m_); 53 | return q_.size(); 54 | } 55 | 56 | template bool 57 | fifo::enq(T e, bool blocking) 58 | { 59 | ScopedLock ml(&m_); 60 | while (1) { 61 | if (!max_ || q_.size() < max_) { 62 | q_.push_back(e); 63 | break; 64 | } 65 | if (blocking) 66 | VERIFY(pthread_cond_wait(&has_space_c_, &m_) == 0); 67 | else 68 | return false; 69 | } 70 | VERIFY(pthread_cond_signal(&non_empty_c_) == 0); 71 | return true; 72 | } 73 | 74 | template void 75 | fifo::deq(T *e) 76 | { 77 | ScopedLock ml(&m_); 78 | 79 | while(1) { 80 | if(q_.empty()){ 81 | VERIFY (pthread_cond_wait(&non_empty_c_, &m_) == 0); 82 | } else { 83 | *e = q_.front(); 84 | q_.pop_front(); 85 | if (max_ && q_.size() < max_) { 86 | VERIFY(pthread_cond_signal(&has_space_c_)==0); 87 | } 88 | break; 89 | } 90 | } 91 | return; 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /yfs/rpc/jsl_log.h: -------------------------------------------------------------------------------- 1 | #ifndef __JSL_LOG_H__ 2 | #define __JSL_LOG_H__ 1 3 | 4 | enum dbcode { 5 | JSL_DBG_OFF = 0, 6 | JSL_DBG_1 = 1, // Critical 7 | JSL_DBG_2 = 2, // Error 8 | JSL_DBG_3 = 3, // Info 9 | JSL_DBG_4 = 4, // Debugging 10 | }; 11 | 12 | extern int JSL_DEBUG_LEVEL; 13 | 14 | #define jsl_log(level,...) \ 15 | do { \ 16 | if(JSL_DEBUG_LEVEL < abs(level)) \ 17 | {;} \ 18 | else { \ 19 | { printf(__VA_ARGS__);} \ 20 | } \ 21 | } while(0) 22 | 23 | void jsl_set_debug(int level); 24 | 25 | #endif // __JSL_LOG_H__ 26 | -------------------------------------------------------------------------------- /yfs/rpc/method_thread.h: -------------------------------------------------------------------------------- 1 | #ifndef method_thread_h 2 | #define method_thread_h 3 | 4 | // method_thread(): start a thread that runs an object method. 5 | // returns a pthread_t on success, and zero on error. 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "lang/verify.h" 12 | 13 | static pthread_t 14 | method_thread_parent(void *(*fn)(void *), void *arg, bool detach) 15 | { 16 | pthread_t th; 17 | pthread_attr_t attr; 18 | pthread_attr_init(&attr); 19 | // set stack size to 100K, so we don't run out of memory 20 | pthread_attr_setstacksize(&attr, 100*1024); 21 | int err = pthread_create(&th, &attr, fn, arg); 22 | pthread_attr_destroy(&attr); 23 | if (err != 0) { 24 | fprintf(stderr, "pthread_create ret %d %s\n", err, strerror(err)); 25 | exit(1); 26 | } 27 | 28 | if (detach) { 29 | // don't keep thread state around after exit, to avoid 30 | // running out of threads. set detach==false if you plan 31 | // to pthread_join. 32 | VERIFY(pthread_detach(th) == 0); 33 | } 34 | 35 | return th; 36 | } 37 | 38 | static void 39 | method_thread_child() 40 | { 41 | // defer pthread_cancel() by default. check explicitly by 42 | // enabling then pthread_testcancel(). 43 | int oldstate, oldtype; 44 | VERIFY(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) == 0); 45 | VERIFY(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype) == 0); 46 | } 47 | 48 | template pthread_t 49 | method_thread(C *o, bool detach, void (C::*m)()) 50 | { 51 | class XXX { 52 | public: 53 | C *o; 54 | void (C::*m)(); 55 | static void *yyy(void *vvv) { 56 | XXX *x = (XXX*)vvv; 57 | C *o = x->o; 58 | void (C::*m)() = x->m; 59 | delete x; 60 | method_thread_child(); 61 | (o->*m)(); 62 | return 0; 63 | } 64 | }; 65 | XXX *x = new XXX; 66 | x->o = o; 67 | x->m = m; 68 | return method_thread_parent(&XXX::yyy, (void *) x, detach); 69 | } 70 | 71 | template pthread_t 72 | method_thread(C *o, bool detach, void (C::*m)(A), A a) 73 | { 74 | class XXX { 75 | public: 76 | C *o; 77 | void (C::*m)(A a); 78 | A a; 79 | static void *yyy(void *vvv) { 80 | XXX *x = (XXX*)vvv; 81 | C *o = x->o; 82 | void (C::*m)(A ) = x->m; 83 | A a = x->a; 84 | delete x; 85 | method_thread_child(); 86 | (o->*m)(a); 87 | return 0; 88 | } 89 | }; 90 | XXX *x = new XXX; 91 | x->o = o; 92 | x->m = m; 93 | x->a = a; 94 | return method_thread_parent(&XXX::yyy, (void *) x, detach); 95 | } 96 | 97 | namespace { 98 | // ~xavid: this causes a bizzare compile error on OS X.5 when 99 | // it's declared in the function, so I moved it out here. 100 | template 101 | class XXX { 102 | public: 103 | C *o; 104 | void (C::*m)(A1 a1, A2 a2); 105 | A1 a1; 106 | A2 a2; 107 | static void *yyy(void *vvv) { 108 | XXX *x = (XXX*)vvv; 109 | C *o = x->o; 110 | void (C::*m)(A1 , A2 ) = x->m; 111 | A1 a1 = x->a1; 112 | A2 a2 = x->a2; 113 | delete x; 114 | method_thread_child(); 115 | (o->*m)(a1, a2); 116 | return 0; 117 | } 118 | }; 119 | } 120 | 121 | template pthread_t 122 | method_thread(C *o, bool detach, void (C::*m)(A1 , A2 ), A1 a1, A2 a2) 123 | { 124 | XXX *x = new XXX; 125 | x->o = o; 126 | x->m = m; 127 | x->a1 = a1; 128 | x->a2 = a2; 129 | return method_thread_parent(&XXX::yyy, (void *) x, detach); 130 | } 131 | 132 | template pthread_t 133 | method_thread(C *o, bool detach, void (C::*m)(A1 , A2, A3 ), A1 a1, A2 a2, A3 a3) 134 | { 135 | class XXX { 136 | public: 137 | C *o; 138 | void (C::*m)(A1 a1, A2 a2, A3 a3); 139 | A1 a1; 140 | A2 a2; 141 | A3 a3; 142 | static void *yyy(void *vvv) { 143 | XXX *x = (XXX*)vvv; 144 | C *o = x->o; 145 | void (C::*m)(A1 , A2 , A3 ) = x->m; 146 | A1 a1 = x->a1; 147 | A2 a2 = x->a2; 148 | A3 a3 = x->a3; 149 | delete x; 150 | method_thread_child(); 151 | (o->*m)(a1, a2, a3); 152 | return 0; 153 | } 154 | }; 155 | XXX *x = new XXX; 156 | x->o = o; 157 | x->m = m; 158 | x->a1 = a1; 159 | x->a2 = a2; 160 | x->a3 = a3; 161 | return method_thread_parent(&XXX::yyy, (void *) x, detach); 162 | } 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /yfs/rpc/pollmgr.h: -------------------------------------------------------------------------------- 1 | #ifndef pollmgr_h 2 | #define pollmgr_h 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __linux__ 8 | #include 9 | #endif 10 | 11 | #define MAX_POLL_FDS 128 12 | 13 | typedef enum { 14 | CB_NONE = 0x0, 15 | CB_RDONLY = 0x1, 16 | CB_WRONLY = 0x10, 17 | CB_RDWR = 0x11, 18 | CB_MASK = ~0x11, 19 | } poll_flag; 20 | 21 | class aio_mgr { 22 | public: 23 | virtual void watch_fd(int fd, poll_flag flag) = 0; 24 | virtual bool unwatch_fd(int fd, poll_flag flag) = 0; 25 | virtual bool is_watched(int fd, poll_flag flag) = 0; 26 | virtual void wait_ready(std::vector *readable, std::vector *writable) = 0; 27 | virtual ~aio_mgr() {} 28 | }; 29 | 30 | class aio_callback { 31 | public: 32 | virtual void read_cb(int fd) = 0; 33 | virtual void write_cb(int fd) = 0; 34 | virtual ~aio_callback() {} 35 | }; 36 | 37 | class PollMgr { 38 | public: 39 | PollMgr(); 40 | ~PollMgr(); 41 | 42 | static PollMgr *Instance(); 43 | static PollMgr *CreateInst(); 44 | 45 | void add_callback(int fd, poll_flag flag, aio_callback *ch); 46 | void del_callback(int fd, poll_flag flag); 47 | bool has_callback(int fd, poll_flag flag, aio_callback *ch); 48 | void block_remove_fd(int fd); 49 | void wait_loop(); 50 | 51 | 52 | static PollMgr *instance; 53 | static int useful; 54 | static int useless; 55 | 56 | private: 57 | pthread_mutex_t m_; 58 | pthread_cond_t changedone_c_; 59 | pthread_t th_; 60 | 61 | aio_callback *callbacks_[MAX_POLL_FDS]; 62 | aio_mgr *aio_; 63 | bool pending_change_; 64 | 65 | }; 66 | 67 | class SelectAIO : public aio_mgr { 68 | public : 69 | 70 | SelectAIO(); 71 | ~SelectAIO(); 72 | void watch_fd(int fd, poll_flag flag); 73 | bool unwatch_fd(int fd, poll_flag flag); 74 | bool is_watched(int fd, poll_flag flag); 75 | void wait_ready(std::vector *readable, std::vector *writable); 76 | 77 | private: 78 | 79 | fd_set rfds_; 80 | fd_set wfds_; 81 | int highfds_; 82 | int pipefd_[2]; 83 | 84 | pthread_mutex_t m_; 85 | 86 | }; 87 | 88 | #ifdef __linux__ 89 | class EPollAIO : public aio_mgr { 90 | public: 91 | EPollAIO(); 92 | ~EPollAIO(); 93 | void watch_fd(int fd, poll_flag flag); 94 | bool unwatch_fd(int fd, poll_flag flag); 95 | bool is_watched(int fd, poll_flag flag); 96 | void wait_ready(std::vector *readable, std::vector *writable); 97 | 98 | private: 99 | int pollfd_; 100 | struct epoll_event ready_[MAX_POLL_FDS]; 101 | int fdstatus_[MAX_POLL_FDS]; 102 | 103 | }; 104 | #endif /* __linux */ 105 | 106 | #endif /* pollmgr_h */ 107 | 108 | -------------------------------------------------------------------------------- /yfs/rpc/slock.h: -------------------------------------------------------------------------------- 1 | #ifndef __SCOPED_LOCK__ 2 | #define __SCOPED_LOCK__ 3 | 4 | #include 5 | #include "lang/verify.h" 6 | struct ScopedLock { 7 | private: 8 | pthread_mutex_t *m_; 9 | public: 10 | ScopedLock(pthread_mutex_t *m): m_(m) { 11 | VERIFY(pthread_mutex_lock(m_)==0); 12 | } 13 | ~ScopedLock() { 14 | VERIFY(pthread_mutex_unlock(m_)==0); 15 | } 16 | }; 17 | #endif /*__SCOPED_LOCK__*/ 18 | -------------------------------------------------------------------------------- /yfs/rpc/thr_pool.h: -------------------------------------------------------------------------------- 1 | #ifndef __THR_POOL__ 2 | #define __THR_POOL__ 3 | 4 | #include 5 | #include 6 | 7 | #include "fifo.h" 8 | 9 | class ThrPool { 10 | 11 | 12 | public: 13 | struct job_t { 14 | void *(*f)(void *); //function point 15 | void *a; //function arguments 16 | }; 17 | 18 | ThrPool(int sz, bool blocking=true); 19 | ~ThrPool(); 20 | template bool addObjJob(C *o, void (C::*m)(A), A a); 21 | void waitDone(); 22 | 23 | bool takeJob(job_t *j); 24 | 25 | private: 26 | pthread_attr_t attr_; 27 | int nthreads_; 28 | bool blockadd_; 29 | 30 | 31 | fifo jobq_; 32 | std::vector th_; 33 | 34 | bool addJob(void *(*f)(void *), void *a); 35 | }; 36 | 37 | template bool 38 | ThrPool::addObjJob(C *o, void (C::*m)(A), A a) 39 | { 40 | 41 | class objfunc_wrapper { 42 | public: 43 | C *o; 44 | void (C::*m)(A a); 45 | A a; 46 | static void *func(void *vvv) { 47 | objfunc_wrapper *x = (objfunc_wrapper*)vvv; 48 | C *o = x->o; 49 | void (C::*m)(A ) = x->m; 50 | A a = x->a; 51 | (o->*m)(a); 52 | delete x; 53 | return 0; 54 | } 55 | }; 56 | 57 | objfunc_wrapper *x = new objfunc_wrapper; 58 | x->o = o; 59 | x->m = m; 60 | x->a = a; 61 | return addJob(&objfunc_wrapper::func, (void *)x); 62 | } 63 | 64 | 65 | #endif 66 | 67 | -------------------------------------------------------------------------------- /yfs/start.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ulimit -c unlimited 4 | 5 | LOSSY=$1 6 | NUM_LS=$2 7 | 8 | if [ -z $NUM_LS ]; then 9 | NUM_LS=0 10 | fi 11 | 12 | BASE_PORT=$RANDOM 13 | BASE_PORT=$[BASE_PORT+2000] 14 | EXTENT_PORT=$BASE_PORT 15 | YFS1_PORT=$[BASE_PORT+2] 16 | YFS2_PORT=$[BASE_PORT+4] 17 | LOCK_PORT=$[BASE_PORT+6] 18 | 19 | YFSDIR1=$PWD/yfs1 20 | YFSDIR2=$PWD/yfs2 21 | 22 | if [ "$LOSSY" ]; then 23 | export RPC_LOSSY=$LOSSY 24 | fi 25 | 26 | if [ $NUM_LS -gt 1 ]; then 27 | x=0 28 | rm config 29 | while [ $x -lt $NUM_LS ]; do 30 | port=$[LOCK_PORT+2*x] 31 | x=$[x+1] 32 | echo $port >> config 33 | done 34 | x=0 35 | while [ $x -lt $NUM_LS ]; do 36 | port=$[LOCK_PORT+2*x] 37 | x=$[x+1] 38 | echo "starting ./lock_server $LOCK_PORT $port > lock_server$x.log 2>&1 &" 39 | ./lock_server $LOCK_PORT $port > lock_server$x.log 2>&1 & 40 | sleep 1 41 | done 42 | else 43 | echo "starting ./lock_server $LOCK_PORT > lock_server.log 2>&1 &" 44 | ./lock_server $LOCK_PORT > lock_server.log 2>&1 & 45 | sleep 1 46 | fi 47 | 48 | unset RPC_LOSSY 49 | 50 | echo "starting ./extent_server $EXTENT_PORT > extent_server.log 2>&1 &" 51 | ./extent_server $EXTENT_PORT > extent_server.log 2>&1 & 52 | sleep 1 53 | 54 | rm -rf $YFSDIR1 55 | mkdir $YFSDIR1 || exit 1 56 | sleep 1 57 | echo "starting ./yfs_client $YFSDIR1 $EXTENT_PORT $LOCK_PORT > yfs_client1.log 2>&1 &" 58 | ./yfs_client $YFSDIR1 $EXTENT_PORT $LOCK_PORT > yfs_client1.log 2>&1 & 59 | sleep 1 60 | 61 | rm -rf $YFSDIR2 62 | mkdir $YFSDIR2 || exit 1 63 | sleep 1 64 | echo "starting ./yfs_client $YFSDIR2 $EXTENT_PORT $LOCK_PORT > yfs_client2.log 2>&1 &" 65 | ./yfs_client $YFSDIR2 $EXTENT_PORT $LOCK_PORT > yfs_client2.log 2>&1 & 66 | 67 | sleep 2 68 | 69 | # make sure FUSE is mounted where we expect 70 | pwd=`pwd -P` 71 | if [ `mount | grep "$pwd/yfs1" | grep -v grep | wc -l` -ne 1 ]; then 72 | sh stop.sh 73 | echo "Failed to mount YFS properly at ./yfs1" 74 | exit -1 75 | fi 76 | 77 | # make sure FUSE is mounted where we expect 78 | if [ `mount | grep "$pwd/yfs2" | grep -v grep | wc -l` -ne 1 ]; then 79 | sh stop.sh 80 | echo "Failed to mount YFS properly at ./yfs2" 81 | exit -1 82 | fi 83 | -------------------------------------------------------------------------------- /yfs/stop.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | YFSDIR1=$PWD/yfs1 4 | YFSDIR2=$PWD/yfs2 5 | 6 | export PATH=$PATH:/usr/local/bin 7 | UMOUNT="umount" 8 | if [ -f "/usr/local/bin/fusermount" -o -f "/usr/bin/fusermount" -o -f "/bin/fusermount" ]; then 9 | UMOUNT="fusermount -u"; 10 | fi 11 | $UMOUNT $YFSDIR1 12 | $UMOUNT $YFSDIR2 13 | killall extent_server 14 | killall yfs_client 15 | killall lock_server 16 | -------------------------------------------------------------------------------- /yfs/test-lab1-part2-a.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | # test CREATE/MKNOD, LOOKUP, READDIR. 4 | 5 | use strict; 6 | 7 | if($#ARGV != 0){ 8 | print STDERR "Usage: test-lab1-part2-a.pl directory\n"; 9 | exit(1); 10 | } 11 | my $dir = $ARGV[0]; 12 | 13 | my $seq = 0; 14 | 15 | my $files = { }; 16 | my @dead; 17 | 18 | for(my $iters = 0; $iters < 200; $iters++){ 19 | createone(); 20 | } 21 | 22 | for(my $iters = 0; $iters < 100; $iters++){ 23 | if(rand() < 0.1){ 24 | livecheck(); 25 | } 26 | if(rand() < 0.1){ 27 | deadcheck(); 28 | } 29 | if(rand() < 0.02){ 30 | dircheck(); 31 | } 32 | if(rand() < 0.5){ 33 | createone(); 34 | } 35 | } 36 | 37 | dircheck(); 38 | printf "Passed all tests!\n"; 39 | exit(0); 40 | 41 | sub createone { 42 | my $name = "file -\n-\t-"; 43 | for(my $i = 0; $i < 40; $i++){ 44 | $name .= sprintf("%c", ord('a') + int(rand(26))); 45 | } 46 | $name .= "-$$-" . $seq; 47 | $seq = $seq + 1; 48 | my $contents = rand(); 49 | print "create $name\n"; 50 | if(!open(F, ">$dir/$name")){ 51 | print STDERR "test-lab1-part2-a: cannot create $dir/$name : $!\n"; 52 | exit(1); 53 | } 54 | close(F); 55 | $files->{$name} = $contents; 56 | } 57 | 58 | sub createagain { 59 | my @a = keys(%$files); 60 | return if $#a < 0; 61 | my $i = int(rand($#a + 1)); 62 | my $k = $a[$i]; 63 | print "re-create $k\n"; 64 | if(!open(F, ">$dir/$k")){ 65 | print STDERR "test-lab1-part2-a: cannot re-create $dir/$k : $!\n"; 66 | exit(1); 67 | } 68 | close(F); 69 | } 70 | 71 | # make sure all the live files are there, 72 | # and that all the dead files are not there. 73 | sub dircheck { 74 | print "dircheck\n"; 75 | opendir(D, $dir); 76 | my %h; 77 | my $f; 78 | while(defined($f = readdir(D))){ 79 | if(!defined($h{$f})){ 80 | $h{$f} = 0; 81 | } 82 | $h{$f} = $h{$f} + 1; 83 | } 84 | closedir(D); 85 | 86 | foreach $f (keys(%$files)){ 87 | if(!defined($h{$f})){ 88 | print STDERR "test-lab1-part2-a.pl: $f is not in the directory listing\n"; 89 | exit(1); 90 | } 91 | if($h{$f} > 1){ 92 | print STDERR "test-lab1-part2-a.pl: $f appears more than once in the directory\n"; 93 | exit(1); 94 | } 95 | } 96 | 97 | foreach $f (@dead){ 98 | if(defined($h{$f})){ 99 | print STDERR "test-lab1-part2-a.pl: $f is dead but in directory listing\n"; 100 | exit(1); 101 | } 102 | } 103 | } 104 | 105 | sub livecheck { 106 | my @a = keys(%$files); 107 | return if $#a < 0; 108 | my $i = int(rand($#a + 1)); 109 | my $k = $a[$i]; 110 | print "livecheck $k\n"; 111 | if(!open(F, "$dir/$k")){ 112 | print STDERR "test-lab1-part2-a: cannot open $dir/$k : $!\n"; 113 | exit(1); 114 | } 115 | close(F); 116 | if( ! -f "$dir/$k" ){ 117 | print STDERR "test-lab1-part2-a: $dir/$k is not of type file\n"; 118 | exit(1); 119 | } 120 | if(open(F, ">$dir/$k/xx")){ 121 | print STDERR "test-lab1-part2-a: $dir/$k acts like a directory, not a file\n"; 122 | exit(1); 123 | } 124 | } 125 | 126 | sub deadcheck { 127 | my $name = "file-$$-" . $seq; 128 | $seq = $seq + 1; 129 | print "check-not-there $name\n"; 130 | if(open(F, "$dir/$name")){ 131 | print STDERR "test-lab1-part2-a: $dir/$name exists but should not\n"; 132 | exit(1); 133 | } 134 | } 135 | 136 | sub deleteone { 137 | my @a = keys(%$files); 138 | return 0 if $#a < 0; 139 | my $i = int(rand($#a + 1)); 140 | my $k = $a[$i]; 141 | print "delete $k\n"; 142 | if(unlink($dir . "/" . $k) == 0){ 143 | print STDERR "test-lab1-part2-a: unlink $k failed: $!\n"; 144 | exit(1); 145 | } 146 | delete $files->{$k}; 147 | push(@dead, $k); 148 | return 1; 149 | } 150 | -------------------------------------------------------------------------------- /yfs/test-lab1-part2-b.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | # Case 1: Single file system 4 | # 1. create new files 5 | # 2. open an existing file 6 | # 3. write to a file 7 | # - write to the middle 8 | # - append 9 | # - write from middle and beyond file length 10 | # - seek beyond file length and write 11 | # 4. read file content 12 | # from each case above 13 | # 14 | # Make sure file handles/file type for new files are correct. 15 | 16 | # Case 2: Two file systems mounted under same root dir. 17 | # 0. Start two fs with same rootdir 18 | # 1. create files in dir1 19 | # 2. read the files from dir2 20 | # 21 | # 22 | 23 | use strict; 24 | $| = 1; 25 | 26 | if($#ARGV != 0){ 27 | print STDERR "Usage: test-lab1-part2-b.pl directory1\n"; 28 | exit(1); 29 | } 30 | my $dir1 = $ARGV[0]; 31 | 32 | my $f1 = "a$$"; 33 | my $f2 = "b$$"; 34 | 35 | my $files = { }; 36 | 37 | print "Write and read one file: "; 38 | writeone($dir1, $f1, 600); 39 | checkcontent($dir1, $f1); 40 | print "OK\n"; 41 | 42 | print "Write and read a second file: "; 43 | writeone($dir1, $f2, 4111); 44 | checkcontent($dir1, $f2); 45 | checkcontent($dir1, $f1); 46 | print "OK\n"; 47 | 48 | print "Overwrite an existing file: "; 49 | writeone($dir1, $f1, 275); # shorter than before... 50 | checkcontent($dir1, $f1); 51 | checkcontent($dir1, $f2); 52 | print "OK\n"; 53 | 54 | print "Append to an existing file: "; 55 | writeone($dir1, $f1, 8192); 56 | append($dir1, $f1, 7007); 57 | checkcontent($dir1, $f1); 58 | print "OK\n"; 59 | 60 | print "Write into the middle of an existing file: "; 61 | writeat($dir1, $f1, 190); 62 | checkcontent($dir1, $f1); 63 | print "OK\n"; 64 | 65 | print "Write beyond the end of an existing file: "; 66 | writeat($dir1, $f1, 65536); 67 | checkcontent($dir1, $f1); 68 | print "OK\n"; 69 | 70 | print "Check that one cannot open non-existant file: "; 71 | checknot($dir1, "z-$$-z"); 72 | print "OK\n"; 73 | 74 | print "Check directory listing: "; 75 | dircheck($dir1); 76 | print "OK\n"; 77 | 78 | print "Passed all tests\n"; 79 | 80 | sub writeone { 81 | my($d, $name, $len) = @_; 82 | my $contents = ""; 83 | 84 | my $f = $d . "/" . $name; 85 | 86 | use FileHandle; 87 | sysopen F, $f, O_TRUNC|O_RDWR|O_CREAT 88 | or die "cannot create $f\n"; 89 | 90 | while(length($contents) < $len){ 91 | $contents .= rand(); 92 | } 93 | $contents = substr($contents, 0, $len); 94 | $files->{$name} = $contents; 95 | 96 | syswrite F, $files->{$name}, length($files->{$name}) 97 | or die "cannot write to $f"; 98 | close(F); 99 | } 100 | 101 | sub checkcontent { 102 | my($d, $name) = @_; 103 | 104 | my $f = $d . "/" . $name; 105 | 106 | open F, "$f" or die "could not open $f for reading"; 107 | my $c2 = ""; 108 | while() { 109 | $c2 .= $_; 110 | } 111 | close(F); 112 | $files->{$name} eq $c2 or die "content of $f is incorrect\n"; 113 | } 114 | 115 | sub checknot { 116 | my($d, $name) = @_; 117 | 118 | my $f = $d . "/" . $name; 119 | 120 | my $x = open(F, $f); 121 | if(defined($x)){ 122 | print STDERR "$x exists but should not\n"; 123 | exit(1); 124 | } 125 | } 126 | 127 | sub append { 128 | my($d, $name, $n) = @_; 129 | 130 | my $f = $d . "/" . $name; 131 | 132 | use FileHandle; 133 | sysopen F, "$f", O_RDWR 134 | or die "cannot open $f for append\n"; 135 | 136 | my $contents = ""; 137 | while(length($contents) < $n){ 138 | $contents .= rand(); 139 | } 140 | $contents = substr($contents, 0, $n); 141 | $files->{$name} .= $contents; ## Append the file content 142 | 143 | seek(F, 0, 2); ## goto end of file 144 | syswrite(F, $contents, length($contents), 0) or die "cannot append to $f"; 145 | close(F); 146 | } 147 | 148 | sub writeat { 149 | my($d, $name, $off) = @_; 150 | 151 | my $f = $d . "/" . $name; 152 | 153 | use FileHandle; 154 | sysopen F, "$f", O_RDWR 155 | or die "cannot open $f for read/write\n"; 156 | 157 | my $contents = rand(); 158 | 159 | my $x = $files->{$name}; 160 | if (length($x) < $off + length($contents)) { 161 | my $nappend = $off + length($contents) - length($x); 162 | for (my $i=0; $i < $nappend; $i++) { 163 | $x .= "\0"; 164 | } 165 | } 166 | substr($x, $off, length($contents)) = $contents; 167 | $files->{$name} = $x; 168 | 169 | seek(F, $off, 0); 170 | syswrite(F, $contents, length($contents), 0) 171 | or die "cannot write $f at offset $off"; 172 | close(F); 173 | } 174 | 175 | sub dircheck { 176 | my($dir) = @_; 177 | 178 | opendir(D, $dir); 179 | my %h; 180 | my $f; 181 | while(defined($f = readdir(D))){ 182 | if(defined($h{$f})){ 183 | print STDERR "$f appears more than once in directory $dir\n"; 184 | exit(1); 185 | } 186 | $h{$f} = 1; 187 | } 188 | closedir(D); 189 | 190 | foreach $f (keys(%$files)){ 191 | if(!defined($h{$f})){ 192 | print STDERR "$f is missing from directory $dir\n"; 193 | exit(1); 194 | } 195 | } 196 | } 197 | 198 | exit(0); 199 | 200 | -------------------------------------------------------------------------------- /yfs/test-lab1-part2-c.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | sub oops { 4 | my($msg) = @_; 5 | print STDERR "test-lab1-part2-c.pl error: $msg : $!\n"; 6 | exit(1); 7 | } 8 | 9 | sub oops1 { 10 | my($msg) = @_; 11 | print STDERR "test-lab1-part2-c.pl error: $msg\n"; 12 | exit(1); 13 | } 14 | 15 | if($#ARGV != 0){ 16 | print STDERR "Usage: test-lab1-part2-c.pl directory\n"; 17 | exit(1); 18 | } 19 | 20 | my $seq = 0; 21 | my $root = $ARGV[0]; 22 | my $dir = $root . "/d" . $$; 23 | print "mkdir $dir\n"; 24 | if(mkdir($dir, 0777) == 0){ 25 | oops("mkdir $dir"); 26 | } 27 | 28 | my $files = { }; 29 | my @dead; 30 | 31 | createone(); 32 | deleteone(); 33 | createone(); 34 | checkmtime(); 35 | checkdirmtime(); 36 | 37 | for($iters = 0; $iters < 10; $iters++){ 38 | createone(); 39 | } 40 | 41 | for($iters = 0; $iters < 50; $iters++){ 42 | if(rand() < 0.2){ 43 | deadcheck(); 44 | } 45 | if(rand() < 0.2){ 46 | livecheck(); 47 | } 48 | if(rand() < 0.02){ 49 | dircheck(); 50 | } 51 | if(rand() < 0.1){ 52 | checkdirmtime(); 53 | } 54 | if(rand() < 0.1){ 55 | checkmtime(); 56 | } 57 | if(rand() < 0.5){ 58 | createone(); 59 | } 60 | if(rand() < 0.5){ 61 | deleteone(); 62 | } 63 | } 64 | 65 | dircheck(); 66 | cleanup(); 67 | dircheck(); 68 | printf "Passed all tests!\n"; 69 | exit(0); 70 | 71 | sub createone { 72 | my $name = "x \t-" . $seq; 73 | $seq = $seq + 1; 74 | my $contents = rand(); 75 | print "create $name\n"; 76 | if(!open(F, ">$dir/$name")){ 77 | oops("cannot create $name"); 78 | } 79 | print F "$contents"; 80 | close(F); 81 | $files->{$name} = $contents; 82 | } 83 | 84 | # make sure all the live files are there, 85 | # and that all the dead files are not there. 86 | sub dircheck { 87 | print "dircheck\n"; 88 | opendir(D, $dir); 89 | my %h; 90 | my $f; 91 | while(defined($f = readdir(D))){ 92 | if(defined($h{$f})){ 93 | oops1("$f occurs twice in directory"); 94 | } 95 | $h{$f} = 1; 96 | } 97 | closedir(D); 98 | 99 | foreach $f (keys(%$files)){ 100 | if(!defined($h{$f})){ 101 | oops1("$f is not in directory listing"); 102 | } 103 | } 104 | 105 | foreach $f (@dead){ 106 | if(defined($h{$f})){ 107 | oops1("$f was removed but is in directory listing"); 108 | } 109 | } 110 | 111 | foreach $f (keys(%h)){ 112 | next if ($f eq "." or $f eq ".."); 113 | if(!defined($files->{$f})){ 114 | oops1("unexpected file $f in directory listing"); 115 | } 116 | } 117 | } 118 | 119 | sub livecheck { 120 | my @a = keys(%$files); 121 | return if $#a < 0; 122 | my $i = int(rand($#a + 1)); 123 | my $k = $a[$i]; 124 | print "livecheck $k\n"; 125 | oops("cannot open $k") if !open(F, "$dir/$k"); 126 | my $z = ; 127 | if($z ne $files->{$k}){ 128 | oops1("file $k wrong contents"); 129 | } 130 | close(F); 131 | } 132 | 133 | sub deadcheck { 134 | return if $#dead < 0; 135 | my $i = int(rand($#dead + 1)); 136 | my $k = $dead[$i]; 137 | return if defined($files->{$k}); # ??? 138 | print "deadcheck $k\n"; 139 | if(rand(1.0) < 0.5){ 140 | if(open(F, $dir . "/" . $k)){ 141 | oops1("dead file $k is readable"); 142 | } 143 | } else { 144 | if(unlink($dir . "/" . $k)){ 145 | oops1("dead file $k was removable"); 146 | } 147 | } 148 | } 149 | 150 | sub deleteone { 151 | my @a = keys(%$files); 152 | return 0 if $#a < 0; 153 | my $i = int(rand($#a + 1)); 154 | my $k = $a[$i]; 155 | print "delete $k\n"; 156 | if(unlink($dir . "/" . $k) == 0){ 157 | oops("unlink $k failed"); 158 | } 159 | delete $files->{$k}; 160 | push(@dead, $k); 161 | return 1; 162 | } 163 | 164 | sub checkdirmtime { 165 | print "checkdirmtime\n"; 166 | opendir(D, $dir); 167 | closedir(D); 168 | my @st1 = stat($dir . "/."); 169 | sleep(2); 170 | my $op; 171 | if(rand() < 0.75){ 172 | return if deleteone() == 0; 173 | $op = "delete"; 174 | } else { 175 | createone(); 176 | $op = "create"; 177 | } 178 | opendir(D, $dir); 179 | closedir(D); 180 | my @st2 = stat($dir . "/."); 181 | if($st1[9] == $st2[9]){ 182 | print $st2[9], " ", $st2[9], "\n"; 183 | oops1("$op did not change directory mtime"); 184 | } 185 | if($st1[10] == $st2[10]){ 186 | oops1("$op did not change directory ctime"); 187 | } 188 | } 189 | 190 | sub checkmtime { 191 | my @a = keys(%$files); 192 | return if $#a < 0; 193 | my $i = int(rand($#a + 1)); 194 | my $k = $a[$i]; 195 | print "checkmtime $k\n"; 196 | 197 | my @st1 = stat("$dir/$k"); 198 | sleep(2); 199 | if(!open(F, ">$dir/$k")){ 200 | oops("cannot re-create $dir/$k"); 201 | } 202 | my @st2 = stat("$dir/$k"); 203 | sleep(2); 204 | print F $files->{$k}; 205 | close(F); 206 | if(!open(F, "$dir/$k")){ 207 | oops("cannot open $dir/$k"); 208 | } 209 | close(F); 210 | my @st3 = stat("$dir/$k"); 211 | 212 | if($st1[9] == $st2[9]){ 213 | oops1("CREATE did not change mtime"); 214 | } 215 | if($st2[9] == $st3[9]){ 216 | oops1("WRITE did not change mtime"); 217 | } 218 | } 219 | 220 | sub cleanup { 221 | while(deleteone()){ 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /yfs/test-lab1-part2-d.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################################## 4 | # this file contains: 5 | # SYMLINK TEST: test for symlink correctness 6 | ########################################### 7 | 8 | DIR=$1 9 | ORIG_FILE=/etc/hosts 10 | 11 | echo "SYMLINK TEST" 12 | rm ${DIR}/hosts ${DIR}/testhostslink ${DIR}/hosts_copy ${DIR}/hosts_copy2 >/dev/null 2>&1 13 | 14 | ln -s ${ORIG_FILE} ${DIR}/hosts 15 | diff ${ORIG_FILE} yfs1/hosts >/dev/null 2>&1 16 | if [ $? -ne 0 ]; 17 | then 18 | echo "failed SYMLINK test" 19 | exit 20 | fi 21 | 22 | cp ${ORIG_FILE} ${DIR}/hosts_copy 23 | ln -s hosts_copy ${DIR}/testhostslink 24 | diff ${DIR}/testhostslink ${DIR}/hosts_copy >/dev/null 2>&1 25 | if [ $? -ne 0 ]; 26 | then 27 | echo "failed SYMLINK test" 28 | exit 29 | fi 30 | 31 | rm ${DIR}/hosts_copy 32 | touch ${DIR}/hosts_copy 33 | diff ${DIR}/testhostslink ${DIR}/hosts_copy >/dev/null 2>&1 34 | if [ $? -ne 0 ]; 35 | then 36 | echo "failed SYMLINK test" 37 | exit 38 | fi 39 | 40 | echo "Passed SYMLINK TEST" 41 | -------------------------------------------------------------------------------- /yfs/test-lab1-part2-e.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################################## 4 | # this file contains: 5 | # BLOBFILE TEST: test for BLOB big file... 6 | ########################################### 7 | 8 | DIR=$1 9 | TEST_FILE1=foo.txt 10 | TEST_FILE2=${DIR}/foo.txt 11 | SRCFILE=tmprand 12 | 13 | dd if=/dev/urandom of=${SRCFILE} bs=1K count=400 >/dev/null 2>&1 14 | 15 | echo "BLOB FILE TEST" 16 | 17 | dd if=${SRCFILE} of=${TEST_FILE1} bs=1K seek=3 count=30 >/dev/null 2>&1 18 | dd if=${SRCFILE} of=${TEST_FILE2} bs=1K seek=3 count=30 >/dev/null 2>&1 19 | diff ${TEST_FILE1} ${TEST_FILE2} >/dev/null 2>&1 20 | if [ $? -ne 0 ]; 21 | then 22 | echo "BLOB FILE TEST FAILED!!!!!!!!!!!!!!!!!!" 23 | exit 24 | fi 25 | echo "Passed BLOB test" 26 | 27 | rm ${TEST_FILE2} ${TEST_FILE1} ${SRCFILE} 28 | -------------------------------------------------------------------------------- /yfs/test-lab1-part2-f.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################################## 4 | # this file contains: 5 | # robustness test 6 | ########################################### 7 | 8 | DIR=$1 9 | 10 | # 11 | #10 times seems a bit too tricky here.... 12 | # setting it to 3.... 13 | # --------------- 14 | # I'm just trying to be nice.... 15 | # 16 | 17 | for times in {0..3} 18 | do 19 | echo "test Round:"$times"" 20 | if ( ! ( perl test-lab1-part2-b.pl $1 | grep -q -i "Passed all tests" )); 21 | then 22 | echo "failed test B yfs1" 23 | exit 24 | fi 25 | if ( ! ( perl test-lab1-part2-a.pl $1 | grep -q -i "Passed all tests" )); 26 | then 27 | echo "failed test A yfs1" 28 | exit 29 | fi 30 | # 31 | #ok this section is maybe a bit cruel here... I'll comment it out 32 | # 33 | #---------------------------------------------------------------------- 34 | #if ( ! ( bash test-lab1-part2-e.sh $1 | grep -q -i "Passed BLOB test" )); 35 | #then 36 | # echo "failed test E yfs1" 37 | # exit 38 | #fi 39 | #rm ${1}/* 2>&1 >/dev/null 40 | # 41 | done 42 | 43 | echo "Passed ROBUSTNESS test" 44 | -------------------------------------------------------------------------------- /yfs/test-lab2-part1-a.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | # test CREATE/MKNOD, LOOKUP, READDIR. 4 | 5 | use strict; 6 | 7 | if($#ARGV != 0){ 8 | print STDERR "Usage: test-lab1-part2-a.pl directory\n"; 9 | exit(1); 10 | } 11 | my $dir = $ARGV[0]; 12 | 13 | my $seq = 0; 14 | 15 | my $files = { }; 16 | my @dead; 17 | 18 | for(my $iters = 0; $iters < 200; $iters++){ 19 | createone(); 20 | } 21 | 22 | for(my $iters = 0; $iters < 100; $iters++){ 23 | if(rand() < 0.1){ 24 | livecheck(); 25 | } 26 | if(rand() < 0.1){ 27 | deadcheck(); 28 | } 29 | if(rand() < 0.02){ 30 | dircheck(); 31 | } 32 | if(rand() < 0.5){ 33 | createone(); 34 | } 35 | } 36 | 37 | dircheck(); 38 | printf "Passed all tests!\n"; 39 | exit(0); 40 | 41 | sub createone { 42 | my $name = "file -\n-\t-"; 43 | for(my $i = 0; $i < 40; $i++){ 44 | $name .= sprintf("%c", ord('a') + int(rand(26))); 45 | } 46 | $name .= "-$$-" . $seq; 47 | $seq = $seq + 1; 48 | my $contents = rand(); 49 | print "create $name\n"; 50 | if(!open(F, ">$dir/$name")){ 51 | print STDERR "test-lab1-part2-a: cannot create $dir/$name : $!\n"; 52 | exit(1); 53 | } 54 | close(F); 55 | $files->{$name} = $contents; 56 | } 57 | 58 | sub createagain { 59 | my @a = keys(%$files); 60 | return if $#a < 0; 61 | my $i = int(rand($#a + 1)); 62 | my $k = $a[$i]; 63 | print "re-create $k\n"; 64 | if(!open(F, ">$dir/$k")){ 65 | print STDERR "test-lab1-part2-a: cannot re-create $dir/$k : $!\n"; 66 | exit(1); 67 | } 68 | close(F); 69 | } 70 | 71 | # make sure all the live files are there, 72 | # and that all the dead files are not there. 73 | sub dircheck { 74 | print "dircheck\n"; 75 | opendir(D, $dir); 76 | my %h; 77 | my $f; 78 | while(defined($f = readdir(D))){ 79 | if(!defined($h{$f})){ 80 | $h{$f} = 0; 81 | } 82 | $h{$f} = $h{$f} + 1; 83 | } 84 | closedir(D); 85 | 86 | foreach $f (keys(%$files)){ 87 | if(!defined($h{$f})){ 88 | print STDERR "test-lab1-part2-a.pl: $f is not in the directory listing\n"; 89 | exit(1); 90 | } 91 | if($h{$f} > 1){ 92 | print STDERR "test-lab1-part2-a.pl: $f appears more than once in the directory\n"; 93 | exit(1); 94 | } 95 | } 96 | 97 | foreach $f (@dead){ 98 | if(defined($h{$f})){ 99 | print STDERR "test-lab1-part2-a.pl: $f is dead but in directory listing\n"; 100 | exit(1); 101 | } 102 | } 103 | } 104 | 105 | sub livecheck { 106 | my @a = keys(%$files); 107 | return if $#a < 0; 108 | my $i = int(rand($#a + 1)); 109 | my $k = $a[$i]; 110 | print "livecheck $k\n"; 111 | if(!open(F, "$dir/$k")){ 112 | print STDERR "test-lab1-part2-a: cannot open $dir/$k : $!\n"; 113 | exit(1); 114 | } 115 | close(F); 116 | if( ! -f "$dir/$k" ){ 117 | print STDERR "test-lab1-part2-a: $dir/$k is not of type file\n"; 118 | exit(1); 119 | } 120 | if(open(F, ">$dir/$k/xx")){ 121 | print STDERR "test-lab1-part2-a: $dir/$k acts like a directory, not a file\n"; 122 | exit(1); 123 | } 124 | } 125 | 126 | sub deadcheck { 127 | my $name = "file-$$-" . $seq; 128 | $seq = $seq + 1; 129 | print "check-not-there $name\n"; 130 | if(open(F, "$dir/$name")){ 131 | print STDERR "test-lab1-part2-a: $dir/$name exists but should not\n"; 132 | exit(1); 133 | } 134 | } 135 | 136 | sub deleteone { 137 | my @a = keys(%$files); 138 | return 0 if $#a < 0; 139 | my $i = int(rand($#a + 1)); 140 | my $k = $a[$i]; 141 | print "delete $k\n"; 142 | if(unlink($dir . "/" . $k) == 0){ 143 | print STDERR "test-lab1-part2-a: unlink $k failed: $!\n"; 144 | exit(1); 145 | } 146 | delete $files->{$k}; 147 | push(@dead, $k); 148 | return 1; 149 | } 150 | -------------------------------------------------------------------------------- /yfs/test-lab2-part1-b.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | # Case 1: Single file system 4 | # 1. create new files 5 | # 2. open an existing file 6 | # 3. write to a file 7 | # - write to the middle 8 | # - append 9 | # - write from middle and beyond file length 10 | # - seek beyond file length and write 11 | # 4. read file content 12 | # from each case above 13 | # 14 | # Make sure file handles/file type for new files are correct. 15 | 16 | # Case 2: Two file systems mounted under same root dir. 17 | # 0. Start two fs with same rootdir 18 | # 1. create files in dir1 19 | # 2. read the files from dir2 20 | # 21 | # 22 | 23 | use strict; 24 | $| = 1; 25 | 26 | if($#ARGV != 0){ 27 | print STDERR "Usage: test-lab1-part2-b.pl directory1\n"; 28 | exit(1); 29 | } 30 | my $dir1 = $ARGV[0]; 31 | 32 | my $f1 = "a$$"; 33 | my $f2 = "b$$"; 34 | 35 | my $files = { }; 36 | 37 | print "Write and read one file: "; 38 | writeone($dir1, $f1, 600); 39 | checkcontent($dir1, $f1); 40 | print "OK\n"; 41 | 42 | print "Write and read a second file: "; 43 | writeone($dir1, $f2, 4111); 44 | checkcontent($dir1, $f2); 45 | checkcontent($dir1, $f1); 46 | print "OK\n"; 47 | 48 | print "Overwrite an existing file: "; 49 | writeone($dir1, $f1, 275); # shorter than before... 50 | checkcontent($dir1, $f1); 51 | checkcontent($dir1, $f2); 52 | print "OK\n"; 53 | 54 | print "Append to an existing file: "; 55 | writeone($dir1, $f1, 8192); 56 | append($dir1, $f1, 7007); 57 | checkcontent($dir1, $f1); 58 | print "OK\n"; 59 | 60 | print "Write into the middle of an existing file: "; 61 | writeat($dir1, $f1, 190); 62 | checkcontent($dir1, $f1); 63 | print "OK\n"; 64 | 65 | print "Write beyond the end of an existing file: "; 66 | writeat($dir1, $f1, 65536); 67 | checkcontent($dir1, $f1); 68 | print "OK\n"; 69 | 70 | print "Check that one cannot open non-existant file: "; 71 | checknot($dir1, "z-$$-z"); 72 | print "OK\n"; 73 | 74 | print "Check directory listing: "; 75 | dircheck($dir1); 76 | print "OK\n"; 77 | 78 | print "Passed all tests\n"; 79 | 80 | sub writeone { 81 | my($d, $name, $len) = @_; 82 | my $contents = ""; 83 | 84 | my $f = $d . "/" . $name; 85 | 86 | use FileHandle; 87 | sysopen F, $f, O_TRUNC|O_RDWR|O_CREAT 88 | or die "cannot create $f\n"; 89 | 90 | while(length($contents) < $len){ 91 | $contents .= rand(); 92 | } 93 | $contents = substr($contents, 0, $len); 94 | $files->{$name} = $contents; 95 | 96 | syswrite F, $files->{$name}, length($files->{$name}) 97 | or die "cannot write to $f"; 98 | close(F); 99 | } 100 | 101 | sub checkcontent { 102 | my($d, $name) = @_; 103 | 104 | my $f = $d . "/" . $name; 105 | 106 | open F, "$f" or die "could not open $f for reading"; 107 | my $c2 = ""; 108 | while() { 109 | $c2 .= $_; 110 | } 111 | close(F); 112 | $files->{$name} eq $c2 or die "content of $f is incorrect\n"; 113 | } 114 | 115 | sub checknot { 116 | my($d, $name) = @_; 117 | 118 | my $f = $d . "/" . $name; 119 | 120 | my $x = open(F, $f); 121 | if(defined($x)){ 122 | print STDERR "$x exists but should not\n"; 123 | exit(1); 124 | } 125 | } 126 | 127 | sub append { 128 | my($d, $name, $n) = @_; 129 | 130 | my $f = $d . "/" . $name; 131 | 132 | use FileHandle; 133 | sysopen F, "$f", O_RDWR 134 | or die "cannot open $f for append\n"; 135 | 136 | my $contents = ""; 137 | while(length($contents) < $n){ 138 | $contents .= rand(); 139 | } 140 | $contents = substr($contents, 0, $n); 141 | $files->{$name} .= $contents; ## Append the file content 142 | 143 | seek(F, 0, 2); ## goto end of file 144 | syswrite(F, $contents, length($contents), 0) or die "cannot append to $f"; 145 | close(F); 146 | } 147 | 148 | sub writeat { 149 | my($d, $name, $off) = @_; 150 | 151 | my $f = $d . "/" . $name; 152 | 153 | use FileHandle; 154 | sysopen F, "$f", O_RDWR 155 | or die "cannot open $f for read/write\n"; 156 | 157 | my $contents = rand(); 158 | 159 | my $x = $files->{$name}; 160 | if (length($x) < $off + length($contents)) { 161 | my $nappend = $off + length($contents) - length($x); 162 | for (my $i=0; $i < $nappend; $i++) { 163 | $x .= "\0"; 164 | } 165 | } 166 | substr($x, $off, length($contents)) = $contents; 167 | $files->{$name} = $x; 168 | 169 | seek(F, $off, 0); 170 | syswrite(F, $contents, length($contents), 0) 171 | or die "cannot write $f at offset $off"; 172 | close(F); 173 | } 174 | 175 | sub dircheck { 176 | my($dir) = @_; 177 | 178 | opendir(D, $dir); 179 | my %h; 180 | my $f; 181 | while(defined($f = readdir(D))){ 182 | if(defined($h{$f})){ 183 | print STDERR "$f appears more than once in directory $dir\n"; 184 | exit(1); 185 | } 186 | $h{$f} = 1; 187 | } 188 | closedir(D); 189 | 190 | foreach $f (keys(%$files)){ 191 | if(!defined($h{$f})){ 192 | print STDERR "$f is missing from directory $dir\n"; 193 | exit(1); 194 | } 195 | } 196 | } 197 | 198 | exit(0); 199 | 200 | -------------------------------------------------------------------------------- /yfs/test-lab2-part1-c.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | sub oops { 4 | my($msg) = @_; 5 | print STDERR "test-lab1-part2-c.pl error: $msg : $!\n"; 6 | exit(1); 7 | } 8 | 9 | sub oops1 { 10 | my($msg) = @_; 11 | print STDERR "test-lab1-part2-c.pl error: $msg\n"; 12 | exit(1); 13 | } 14 | 15 | if($#ARGV != 0){ 16 | print STDERR "Usage: test-lab1-part2-c.pl directory\n"; 17 | exit(1); 18 | } 19 | 20 | my $seq = 0; 21 | my $root = $ARGV[0]; 22 | my $dir = $root . "/d" . $$; 23 | print "mkdir $dir\n"; 24 | if(mkdir($dir, 0777) == 0){ 25 | oops("mkdir $dir"); 26 | } 27 | 28 | my $files = { }; 29 | my @dead; 30 | 31 | createone(); 32 | deleteone(); 33 | createone(); 34 | checkmtime(); 35 | checkdirmtime(); 36 | 37 | for($iters = 0; $iters < 10; $iters++){ 38 | createone(); 39 | } 40 | 41 | for($iters = 0; $iters < 50; $iters++){ 42 | if(rand() < 0.2){ 43 | deadcheck(); 44 | } 45 | if(rand() < 0.2){ 46 | livecheck(); 47 | } 48 | if(rand() < 0.02){ 49 | dircheck(); 50 | } 51 | if(rand() < 0.1){ 52 | checkdirmtime(); 53 | } 54 | if(rand() < 0.1){ 55 | checkmtime(); 56 | } 57 | if(rand() < 0.5){ 58 | createone(); 59 | } 60 | if(rand() < 0.5){ 61 | deleteone(); 62 | } 63 | } 64 | 65 | dircheck(); 66 | cleanup(); 67 | dircheck(); 68 | printf "Passed all tests!\n"; 69 | exit(0); 70 | 71 | sub createone { 72 | my $name = "x \t-" . $seq; 73 | $seq = $seq + 1; 74 | my $contents = rand(); 75 | print "create $name\n"; 76 | if(!open(F, ">$dir/$name")){ 77 | oops("cannot create $name"); 78 | } 79 | print F "$contents"; 80 | close(F); 81 | $files->{$name} = $contents; 82 | } 83 | 84 | # make sure all the live files are there, 85 | # and that all the dead files are not there. 86 | sub dircheck { 87 | print "dircheck\n"; 88 | opendir(D, $dir); 89 | my %h; 90 | my $f; 91 | while(defined($f = readdir(D))){ 92 | if(defined($h{$f})){ 93 | oops1("$f occurs twice in directory"); 94 | } 95 | $h{$f} = 1; 96 | } 97 | closedir(D); 98 | 99 | foreach $f (keys(%$files)){ 100 | if(!defined($h{$f})){ 101 | oops1("$f is not in directory listing"); 102 | } 103 | } 104 | 105 | foreach $f (@dead){ 106 | if(defined($h{$f})){ 107 | oops1("$f was removed but is in directory listing"); 108 | } 109 | } 110 | 111 | foreach $f (keys(%h)){ 112 | next if ($f eq "." or $f eq ".."); 113 | if(!defined($files->{$f})){ 114 | oops1("unexpected file $f in directory listing"); 115 | } 116 | } 117 | } 118 | 119 | sub livecheck { 120 | my @a = keys(%$files); 121 | return if $#a < 0; 122 | my $i = int(rand($#a + 1)); 123 | my $k = $a[$i]; 124 | print "livecheck $k\n"; 125 | oops("cannot open $k") if !open(F, "$dir/$k"); 126 | my $z = ; 127 | if($z ne $files->{$k}){ 128 | oops1("file $k wrong contents"); 129 | } 130 | close(F); 131 | } 132 | 133 | sub deadcheck { 134 | return if $#dead < 0; 135 | my $i = int(rand($#dead + 1)); 136 | my $k = $dead[$i]; 137 | return if defined($files->{$k}); # ??? 138 | print "deadcheck $k\n"; 139 | if(rand(1.0) < 0.5){ 140 | if(open(F, $dir . "/" . $k)){ 141 | oops1("dead file $k is readable"); 142 | } 143 | } else { 144 | if(unlink($dir . "/" . $k)){ 145 | oops1("dead file $k was removable"); 146 | } 147 | } 148 | } 149 | 150 | sub deleteone { 151 | my @a = keys(%$files); 152 | return 0 if $#a < 0; 153 | my $i = int(rand($#a + 1)); 154 | my $k = $a[$i]; 155 | print "delete $k\n"; 156 | if(unlink($dir . "/" . $k) == 0){ 157 | oops("unlink $k failed"); 158 | } 159 | delete $files->{$k}; 160 | push(@dead, $k); 161 | return 1; 162 | } 163 | 164 | sub checkdirmtime { 165 | print "checkdirmtime\n"; 166 | opendir(D, $dir); 167 | closedir(D); 168 | my @st1 = stat($dir . "/."); 169 | sleep(2); 170 | my $op; 171 | if(rand() < 0.75){ 172 | return if deleteone() == 0; 173 | $op = "delete"; 174 | } else { 175 | createone(); 176 | $op = "create"; 177 | } 178 | opendir(D, $dir); 179 | closedir(D); 180 | my @st2 = stat($dir . "/."); 181 | if($st1[9] == $st2[9]){ 182 | print $st2[9], " ", $st2[9], "\n"; 183 | oops1("$op did not change directory mtime"); 184 | } 185 | if($st1[10] == $st2[10]){ 186 | oops1("$op did not change directory ctime"); 187 | } 188 | } 189 | 190 | sub checkmtime { 191 | my @a = keys(%$files); 192 | return if $#a < 0; 193 | my $i = int(rand($#a + 1)); 194 | my $k = $a[$i]; 195 | print "checkmtime $k\n"; 196 | 197 | my @st1 = stat("$dir/$k"); 198 | sleep(2); 199 | if(!open(F, ">$dir/$k")){ 200 | oops("cannot re-create $dir/$k"); 201 | } 202 | my @st2 = stat("$dir/$k"); 203 | sleep(2); 204 | print F $files->{$k}; 205 | close(F); 206 | if(!open(F, "$dir/$k")){ 207 | oops("cannot open $dir/$k"); 208 | } 209 | close(F); 210 | my @st3 = stat("$dir/$k"); 211 | 212 | if($st1[9] == $st2[9]){ 213 | oops1("CREATE did not change mtime"); 214 | } 215 | if($st2[9] == $st3[9]){ 216 | oops1("WRITE did not change mtime"); 217 | } 218 | } 219 | 220 | sub cleanup { 221 | while(deleteone()){ 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /yfs/test-lab2-part1-d.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################################## 4 | # this file contains: 5 | # SYMLINK TEST: test for symlink correctness 6 | ########################################### 7 | 8 | DIR=$1 9 | ORIG_FILE=/etc/hosts 10 | 11 | echo "SYMLINK TEST" 12 | rm ${DIR}/hosts ${DIR}/testhostslink ${DIR}/hosts_copy ${DIR}/hosts_copy2 >/dev/null 2>&1 13 | 14 | ln -s ${ORIG_FILE} ${DIR}/hosts 15 | diff ${ORIG_FILE} $DIR/hosts >/dev/null 2>&1 16 | if [ $? -ne 0 ]; 17 | then 18 | echo "failed SYMLINK test" 19 | exit 20 | fi 21 | 22 | cp ${ORIG_FILE} $DIR/hosts_copy 23 | ln -s hosts_copy $DIR/testhostslink 24 | diff $DIR/testhostslink $DIR/hosts_copy >/dev/null 2>&1 25 | if [ $? -ne 0 ]; 26 | then 27 | echo "failed SYMLINK test" 28 | exit 29 | fi 30 | 31 | rm $DIR/hosts_copy 32 | touch $DIR/hosts_copy 33 | diff $DIR/testhostslink $DIR/hosts_copy >/dev/null 2>&1 34 | if [ $? -ne 0 ]; 35 | then 36 | echo "failed SYMLINK test" 37 | exit 38 | fi 39 | 40 | echo "Passed SYMLINK TEST" -------------------------------------------------------------------------------- /yfs/test-lab2-part1-e.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################################## 4 | # this file contains: 5 | # BLOBFILE TEST: test for BLOB big file... 6 | ########################################### 7 | 8 | DIR=$1 9 | SUFFIX=$(echo $DIR | grep -o -P 'yfs\d' | head) 10 | TEST_FILE1=foo.txt.${SUFFIX} 11 | TEST_FILE2=${DIR}/foo.txt.${SUFFIX} 12 | SRCFILE=tmprand 13 | 14 | dd if=/dev/urandom of=${SRCFILE} bs=1K count=400 >/dev/null 2>&1 15 | 16 | echo "BLOB FILE TEST" 17 | 18 | dd if=${SRCFILE} of=${TEST_FILE1} bs=1K seek=3 count=30 >/dev/null 2>&1 19 | dd if=${SRCFILE} of=${TEST_FILE2} bs=1K seek=3 count=30 >/dev/null 2>&1 20 | diff ${TEST_FILE1} ${TEST_FILE2} >/dev/null 2>&1 21 | if [ $? -ne 0 ]; 22 | then 23 | echo "BLOB FILE TEST FAILED!!!!!!!!!!!!!!!!!!" 24 | exit 25 | fi 26 | echo "Passed BLOB test" 27 | 28 | rm ${TEST_FILE2} ${TEST_FILE1} ${SRCFILE} -------------------------------------------------------------------------------- /yfs/test-lab2-part1-f.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################################## 4 | # this file contains: 5 | # robustness test 6 | ########################################### 7 | 8 | DIR=$1 9 | 10 | # 11 | #10 times seems a bit too tricky here.... 12 | # setting it to 3.... 13 | # --------------- 14 | # I'm just trying to be nice.... 15 | # 16 | 17 | for times in {0..3} 18 | do 19 | echo "test Round:"$times"" 20 | if ( ! ( perl test-lab1-part2-b.pl $1 | grep -q -i "Passed all tests" )); 21 | then 22 | echo "failed test B yfs1" 23 | exit 24 | fi 25 | if ( ! ( perl test-lab1-part2-a.pl $1 | grep -q -i "Passed all tests" )); 26 | then 27 | echo "failed test A yfs1" 28 | exit 29 | fi 30 | # 31 | #ok this section is maybe a bit cruel here... I'll comment it out 32 | # 33 | #---------------------------------------------------------------------- 34 | #if ( ! ( bash test-lab1-part2-e.sh $1 | grep -q -i "Passed BLOB test" )); 35 | #then 36 | # echo "failed test E yfs1" 37 | # exit 38 | #fi 39 | #rm ${1}/* 2>&1 >/dev/null 40 | # 41 | done 42 | 43 | echo "Passed ROBUSTNESS test" 44 | -------------------------------------------------------------------------------- /yfs/test-lab4-part0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | . test-lab4-common.sh 4 | 5 | check_network() { 6 | # Check hostname 7 | echo "Check hostname..." 8 | myname=$(hostname) 9 | if [[ "x$myname" != "xapp" && "x$myname" != "xname" && "x$myname" != "xdata1" && "x$myname" != "xdata2" ]]; then 10 | echo "You didn't setup host name correctly" 11 | exit 1 12 | fi 13 | 14 | # Check hosts 15 | echo "Check /etc/hosts..." 16 | if ! (grep -v "^#" /etc/hosts | grep app >/dev/null); then 17 | echo "You didn't setup /etc/hosts correctly" 18 | exit 1 19 | fi 20 | if ! (grep -v "^#" /etc/hosts | grep name >/dev/null); then 21 | echo "You didn't setup /etc/hosts correctly" 22 | exit 1 23 | fi 24 | if ! (grep -v "^#" /etc/hosts | grep data1 >/dev/null); then 25 | echo "You didn't setup /etc/hosts correctly" 26 | exit 1 27 | fi 28 | if ! (grep -v "^#" /etc/hosts | grep data2 >/dev/null); then 29 | echo "You didn't setup /etc/hosts correctly" 30 | exit 1 31 | fi 32 | 33 | # Check self ip 34 | echo "Check self IP resolution..." 35 | myip=$(grep -v "^#" /etc/hosts | grep "$myname" | grep -o -E "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+") 36 | mynic=$(ip link | grep -o -P "(?<=: ).*(?=:)" | grep -v lo) 37 | mynicip="" 38 | for nic in $mynic; do 39 | mynicip="$mynicip "$(ip addr show dev $nic | grep -o -P "(?<=inet )[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+") 40 | done 41 | if ! (echo $mynicip | grep -F "$myip" >/dev/null); then 42 | echo "Resolved IP ($myip) of your host name ($myname) is not your IP" 43 | echo "You should check your /etc/hosts" 44 | exit 1 45 | fi 46 | 47 | # Check connectivity 48 | echo "Check connectivity..." 49 | for target in app name data1 data2; do 50 | if ! (ping -c 1 -w 3 $target >/dev/null 2>&1); then 51 | echo "Can't connect to $target" 52 | echo "You should check $myname and $target's network configuration" 53 | exit 1 54 | fi 55 | done 56 | 57 | if [ "x$myname" == "xapp" ]; then 58 | # Check passwordless SSH 59 | echo "Check passwordless SSH..." 60 | for target in app name data1 data2; do 61 | if ! ($SSH $target /bin/bash -c exit); then 62 | echo "Can't ssh to $target without password" 63 | echo "You should check the ssh key on $myname and authorized_keys on $target" 64 | exit 1 65 | fi 66 | done 67 | 68 | # Check TA key 69 | echo "Check TA's public key..." 70 | if ! (grep "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPYzrRrs4AKIaEK8AxZxqCHRb1LwxBpRz61zfsw3U9zPcyyPxruiz8sK7ph9+r7Z0dA6rfJY6suO/uQosC5X7NtW0zvplePm4GzxEPKBWtGYC9H3lwU8hZBXhgcNRphRPCITImC4d7/TB+qib7cBzlRO2F9y4k2OcQRnNAiHdq8vmdvxptiT/345F732Ijqyi5hjKE66bIufcmiJi/GugqeBgs8oPnWRMCedzVs17E59nbOUIYqJLQgsz1HD/KGR9Pu3niuTd6djze9c7sFfLQRNZL5TqeWGCPXbYAQYgQMQ/angtsLdKwnh+6Cn5xgwSPBlblbSKiRfD9qkOtx2AH" ~/.ssh/authorized_keys >/dev/null 2>&1); then 71 | echo "You didn't add TA's public key to your authorized_keys." 72 | exit 1 73 | fi 74 | 75 | # Check IP correctness 76 | echo "Check IP correctness..." 77 | for target in app name data1 data2; do 78 | report_name=$($SSH $target /bin/hostname 2>/dev/null) 79 | if [ "x$report_name" != "x$target" ]; then 80 | echo "SSH to $target but it reports \"I'm $report_name\"" 81 | exit 1 82 | fi 83 | done 84 | fi 85 | 86 | if [ "x$myname" != "xapp" ]; then 87 | echo "$myname pass" 88 | exit 0 89 | else 90 | # Check on other host 91 | echo "Check basic configuration on other hosts..." 92 | for target in name data1 data2; do 93 | quiet $SCP test-lab4-common.sh test-lab4-part0.sh $target: 94 | result=$(quiet_err $SSH $target /home/cse/test-lab4-part0.sh) 95 | quiet $SSH $target rm test-lab4-common.sh test-lab4-part0.sh 96 | if ! (echo "$result" | grep "$target pass" >/dev/null); then 97 | echo "$result" | sed "s/^/$target: /" 98 | exit 1 99 | fi 100 | done 101 | fi 102 | } 103 | 104 | if [ -f app_public_ip ]; then 105 | safe_run $SCP test-lab4-common.sh test-lab4-part0.sh cse@$(cat app_public_ip): 106 | remote_grade /home/cse/test-lab4-part0.sh 107 | ret=$? 108 | safe_run $SSH cse@$(cat app_public_ip) rm test-lab4-common.sh test-lab4-part0.sh 109 | exit $ret 110 | fi 111 | 112 | check_network 113 | -------------------------------------------------------------------------------- /yfs/threader.h: -------------------------------------------------------------------------------- 1 | #ifndef THREADER_H_ 2 | #define THREADER_H_ 3 | template 4 | struct ThreadArg { 5 | C *that; 6 | Fn fn; 7 | T1 a1; 8 | T2 a2; 9 | }; 10 | template 11 | void *ThreadCall(void *_arg) { 12 | ThreadArg *arg = (ThreadArg *) _arg; 13 | (arg->that->*(arg->fn))(); 14 | delete arg; 15 | return NULL; 16 | } 17 | template 18 | void *ThreadCall(void *_arg) { 19 | ThreadArg *arg = (ThreadArg *) _arg; 20 | (arg->that->*(arg->fn))(arg->a1); 21 | delete arg; 22 | return NULL; 23 | } 24 | template 25 | void *ThreadCall(void *_arg) { 26 | ThreadArg *arg = (ThreadArg *) _arg; 27 | (arg->that->*(arg->fn))(arg->a1, arg->a2); 28 | delete arg; 29 | return NULL; 30 | } 31 | template 32 | void NewThread(C *that, void (C::*fn)()) { 33 | ThreadArg *arg = new ThreadArg(); 34 | arg->that = that; 35 | arg->fn = fn; 36 | pthread_t thread; 37 | pthread_create(&thread, NULL, ThreadCall, arg); 38 | } 39 | template 40 | void NewThread(C *that, void (C::*fn)(T1 a1), const T1 &a1) { 41 | ThreadArg *arg = new ThreadArg(); 42 | arg->that = that; 43 | arg->fn = fn; 44 | arg->a1 = a1; 45 | pthread_t thread; 46 | pthread_create(&thread, NULL, ThreadCall, arg); 47 | } 48 | template 49 | void NewThread(C *that, void (C::*fn)(T1 a1, T2 a2), const T1 &a1, const T2 &a2) { 50 | ThreadArg *arg = new ThreadArg(); 51 | arg->that = that; 52 | arg->fn = fn; 53 | arg->a1 = a1; 54 | pthread_t thread; 55 | pthread_create(&thread, NULL, ThreadCall, arg); 56 | } 57 | #endif 58 | -------------------------------------------------------------------------------- /yfs/tprintf.h: -------------------------------------------------------------------------------- 1 | #ifndef TPRINTF_H 2 | #define TPRINTF_H 3 | 4 | #define tprintf(args...) do { \ 5 | struct timeval tv; \ 6 | gettimeofday(&tv, 0); \ 7 | printf("%ld:\t", tv.tv_sec * 1000 + tv.tv_usec / 1000);\ 8 | printf(args); \ 9 | } while (0); 10 | #endif 11 | -------------------------------------------------------------------------------- /yfs/yfs_client.h: -------------------------------------------------------------------------------- 1 | #ifndef yfs_client_h 2 | #define yfs_client_h 3 | 4 | #include 5 | 6 | #include "lock_protocol.h" 7 | #include "lock_client.h" 8 | #include "lock_client_cache.h" 9 | 10 | //#include "yfs_protocol.h" 11 | #include "extent_client.h" 12 | #include 13 | 14 | 15 | class yfs_client { 16 | extent_client *ec; 17 | lock_client *lc; 18 | public: 19 | 20 | typedef unsigned long long inum; 21 | enum xxstatus { OK, RPCERR, NOENT, IOERR, EXIST }; 22 | typedef int status; 23 | 24 | struct fileinfo { 25 | unsigned long long size; 26 | unsigned long atime; 27 | unsigned long mtime; 28 | unsigned long ctime; 29 | }; 30 | struct dirinfo { 31 | unsigned long atime; 32 | unsigned long mtime; 33 | unsigned long ctime; 34 | }; 35 | struct symlinkinfo 36 | { 37 | unsigned long long size; 38 | unsigned int atime; 39 | unsigned int mtime; 40 | unsigned int ctime; 41 | }; 42 | struct dirent { 43 | std::string name; 44 | yfs_client::inum inum; 45 | }; 46 | 47 | private: 48 | static std::string filename(inum); 49 | static inum n2i(std::string); 50 | 51 | public: 52 | yfs_client(std::string, std::string); 53 | yfs_client(extent_client*, lock_client*); 54 | 55 | bool nlock_isfile(inum); 56 | bool isfile(inum); 57 | bool nlock_isdir(inum); 58 | bool isdir(inum); 59 | bool nlock_islink(inum inum); 60 | bool islink(inum inum); 61 | 62 | int getfile(inum, fileinfo &); 63 | int getdir(inum, dirinfo &); 64 | 65 | int setattr(inum, size_t); 66 | //lookup is used by other function, use nlock_lookup to avoid repetitive lock 67 | int nlock_lookup(inum, const char *, bool &, inum &); 68 | int lookup(inum, const char *, bool &, inum &); 69 | int nlock_create(inum, const char *, mode_t, inum &); 70 | int create(inum, const char *, mode_t, inum &); 71 | int nlock_readdir(inum, std::list &); 72 | int readdir(inum, std::list &); 73 | int write(inum, size_t, off_t, const char *, size_t &); 74 | int read(inum, size_t, off_t, std::string &); 75 | int nlock_unlink(inum,const char *); 76 | int unlink(inum,const char *); 77 | int mkdir(inum , const char *, mode_t , inum &); 78 | int createlink(inum parent ,std::string link_name, std::string target_name, inum &ino_out); 79 | int readlink(inum inum ,std::string &link_name); 80 | 81 | /** you may need to add symbolic link related methods here.*/ 82 | }; 83 | 84 | #endif --------------------------------------------------------------------------------