From 91d3c5f829804636ff9e1012132babe7226a97a5 Mon Sep 17 00:00:00 2001 From: randomdan Date: Mon, 2 Nov 2009 19:41:53 +0000 Subject: Single msg read dir and reconnects --- netfs/daemon.cpp | 73 +++++++++++++++++++++++++++++++---------------- netfs/daemonDirs.cpp | 14 ++------- netfs/fuse.cpp | 80 ++++++++++++++++++++++++++++++---------------------- netfs/fuse.h | 13 +++------ netfs/fuseDirs.cpp | 7 ++--- netfs/msgtypes.cpp | 30 ++++++++++++++++++-- netfs/msgtypes.h | 18 ++++++------ 7 files changed, 141 insertions(+), 94 deletions(-) diff --git a/netfs/daemon.cpp b/netfs/daemon.cpp index b029316..4876a1a 100644 --- a/netfs/daemon.cpp +++ b/netfs/daemon.cpp @@ -21,8 +21,32 @@ void Sender::Send(DataPayloadPtr p) r->write(host); } +class TempUserChange { + public: + TempUserChange(uid_t u, gid_t g) : + ogid(getegid()), + ouid(geteuid()) + { + errno = 0; + setegid(g); + seteuid(u); + } + ~TempUserChange() + { + setegid(ogid); + seteuid(ouid); + } + private: + gid_t ogid; + uid_t ouid; +}; + #define TRYCLASS(cls) \ - if (type == cls::TypeID) { handle(p->data.as >(), s); } + if (type == cls::TypeID) { \ + TypedPayload::Ptr tp = p->data.as >(); \ + TempUserChange tuc(tp->data.uid, tp->data.gid); \ + handle(tp, s); \ + } void runDaemonOn(FILE * f, DaemonConfigPtr, DaemonGlobalStatePtr) @@ -65,31 +89,32 @@ runDaemonOn(FILE * f, DaemonConfigPtr, DaemonGlobalStatePtr) int main(int, char* []) { DaemonConfigPtr dc = DaemonConfig::Load("daemon.xml"); - struct addrinfo hints; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - struct addrinfo *result, *rp; - int s = getaddrinfo(NULL, dc->tcpPort.c_str(), &hints, &result); - if (s) { - // Error - } - for (rp = result; rp != NULL; rp = rp->ai_next) { - int sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - if (sfd == -1) - continue; - if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) { - if (listen(sfd, 5)) { - // Error - } - DaemonGlobalStatePtr dgs = new DaemonGlobalState(); - for (int newfd; (newfd = accept(sfd, NULL, NULL)) > 0; ) { - runDaemonOn(fdopen(newfd, "a+"), dc, dgs); + DaemonGlobalStatePtr dgs = new DaemonGlobalState(); + while (true) { + struct addrinfo hints; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + struct addrinfo *result, *rp; + if (getaddrinfo(NULL, dc->tcpPort.c_str(), &hints, &result) == 0) { + for (rp = result; rp != NULL; rp = rp->ai_next) { + int sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (sfd == -1) + continue; + if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) { + if (listen(sfd, 5)) { + // Error + continue; + } + for (int newfd; (newfd = accept(sfd, NULL, NULL)) > 0; ) { + runDaemonOn(fdopen(newfd, "a+"), dc, dgs); + } + break; + } + close(sfd); } - break; } - close(sfd); } return 0; } diff --git a/netfs/daemonDirs.cpp b/netfs/daemonDirs.cpp index 89b2426..20ab82d 100644 --- a/netfs/daemonDirs.cpp +++ b/netfs/daemonDirs.cpp @@ -37,27 +37,19 @@ handler(CloseDirRequest) } s.Send(r); } -typedef TypedPayload::Ptr DirContPLPtr; -typedef TypedPayload DirContPL; -typedef std::set DirContPLs; handler(ReadDirRequest) { TypedPayload * r = new TypedPayload(); if (dirs.find(req->data.handle) != dirs.end()) { errno = 0; dirent * d; - DirContPLs ds; while ((d = readdir(dirs[req->data.handle])) && errno == 0) { - DirContPLPtr dc = new DirContPL(); - dc->data.path = d->d_name; - ds.insert(dc); + r->data.entries.push_back(ReadDirReply::Entry()); + r->data.entries.back().path = d->d_name; + stat("/", &r->data.entries.back().val); } r->data.error = errno; - r->data.count = ds.size(); s.Send(r); - foreach(DirContPLs::const_iterator, ds, dir) { - s.Send(*dir); - } } else { r->data.error = EBADF; diff --git a/netfs/fuse.cpp b/netfs/fuse.cpp index c540af1..ceb5cb3 100644 --- a/netfs/fuse.cpp +++ b/netfs/fuse.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "fuse.h" static FuseAppBase * fuseApp; @@ -71,27 +72,32 @@ static void fuseDestroy(void * x) NetFS::NetFS() : f(NULL) { - struct addrinfo hints; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - struct addrinfo *result, *rp; - int s = getaddrinfo("localhost", "4000", &hints, &result); - if (s) { - // Error - } - for (rp = result; rp != NULL; rp = rp->ai_next) { - int sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - if (sfd == -1) - // Error - continue; - if (connect(sfd, rp->ai_addr, rp->ai_addrlen)) { - // Error - continue; +} +void +NetFS::connect() +{ + while (!f) { + struct addrinfo hints; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + struct addrinfo *result, *rp; + if (getaddrinfo("localhost", "4000", &hints, &result) == 0) { + for (rp = result; rp != NULL; rp = rp->ai_next) { + int sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (sfd == -1) + // Error + continue; + if (::connect(sfd, rp->ai_addr, rp->ai_addrlen)) { + // Error + continue; + } + f = fdopen(sfd, "a+"); + break; + } } - f = fdopen(sfd, "a+"); - break; + sleep(5); } } NetFS::~NetFS() @@ -103,20 +109,22 @@ NetFS::~NetFS() DataPayloadPtr NetFS::exchange(DataPayloadPtr dp) { - send(dp); - return recv(); -} -void -NetFS::send(DataPayloadPtr dp) -{ + AutoMutex a(comms); + PacketPtr recvd; PacketPtr sendme = new Packet(0, dp); - sendme->write(f); -} -DataPayloadPtr -NetFS::recv() -{ - PacketPtr recvd = new Packet(f); - return recvd->data; + connect(); + while (true) { + try { + sendme->write(f); + recvd = new Packet(f); + return recvd->data; + } + catch (...) { + f = NULL; + connect(); + } + } + return NULL; } template @@ -165,7 +173,11 @@ int runFuseApp(int argc, char* argv[]) fuseCall, fuseCall, fuseCall, - fuseCall + fuseCall, + NULL, + NULL, + NULL, + NULL }; struct fuse_args args = FUSE_ARGS_INIT(argc, argv); if (fuse_opt_parse(&args, fuseApp, fuse_opts, diff --git a/netfs/fuse.h b/netfs/fuse.h index dc0a124..f587da4 100644 --- a/netfs/fuse.h +++ b/netfs/fuse.h @@ -3,6 +3,7 @@ #include "fuseapp.h" #include "comms.h" +#include "threads.h" class NetFS : public FuseAppBase { @@ -38,16 +39,10 @@ class NetFS : public FuseAppBase NetFS(); ~NetFS(); DataPayloadPtr exchange(DataPayloadPtr dp); - void send(DataPayloadPtr dp); - DataPayloadPtr recv(); - template - SmartPointer > recvType() - { - DataPayloadPtr p = this->recv(); - return p.as >(); - } private: - FILE * f; + FILE * f; + void connect(); + Mutex comms; }; // this needs to go here to avoid circular includes regarding the net->exchange call diff --git a/netfs/fuseDirs.cpp b/netfs/fuseDirs.cpp index 17e4a3e..f756393 100644 --- a/netfs/fuseDirs.cpp +++ b/netfs/fuseDirs.cpp @@ -1,5 +1,6 @@ #include "fuse.h" #include "msgtypes.h" +#include "misc.h" int NetFS::opendir(const char * p, struct fuse_file_info * fi) @@ -24,10 +25,8 @@ NetFS::readdir(const char *, void * buf, fuse_fill_dir_t filler, off_t, struct f TypedPayloadReq::Ptr msg = new TypedPayloadReq(fuse_get_context()); msg->data.handle = fi->fh; TypedPayload::Ptr rep = msg->exchange(this); - size_t cnt = rep->data.count; - while (cnt--) { - TypedPayload::Ptr dir = recvType(); - filler(buf, dir->data.path.c_str(), &dir->data.val, 0); + foreach (std::vector::const_iterator, rep->data.entries, e) { + filler(buf, e->path.c_str(), &e->val, 0); } return -rep->data.error; } diff --git a/netfs/msgtypes.cpp b/netfs/msgtypes.cpp index 9ac6b04..6ea3c80 100644 --- a/netfs/msgtypes.cpp +++ b/netfs/msgtypes.cpp @@ -1,5 +1,6 @@ #include "msgtypes.h" #include "xfers.h" +#include "misc.h" MessageFactories & MsgFacs() { @@ -69,7 +70,6 @@ RequestBase::Read(FILE*f) } Xfer1(3, OpenDirRequest, RequestBase, path) Xfer2(4, OpenDirReply, ContentBase, error, handle) -Xfer2(5, ReadDirReply, ContentBase, error, count) Xfer1(6, ReadDirRequest, RequestBase, handle) Xfer2(7, AccessRequest, RequestBase, path, access) Xfer1(8, SimpleInt, ContentBase, value) @@ -77,7 +77,6 @@ Xfer1(9, GetAttrRequest, RequestBase, path) Xfer2(10, GetAttrReply, ContentBase, res, val) Xfer1(11, CloseDirRequest, RequestBase, handle) Xfer1(12, CloseDirReply, ContentBase, error) -Xfer2(13, ReadDirContent, ContentBase, path, val) Xfer1(14, OpenRequest, RequestBase, path) Xfer2(15, OpenReply, ContentBase, error, handle) Xfer1(16, CloseRequest, RequestBase, handle) @@ -101,6 +100,33 @@ Xfer1(33, FgetAttrRequest, RequestBase, handle) Xfer2(34, CreateRequest, RequestBase, path, mode) Xfer1(35, RmDirRequest, RequestBase, path) +MSGTYPE(5, ReadDirReply) +void +ReadDirReply::Send(FILE*f) const +{ + ContentBase::Send(f); + *f << error; + *f << entries.size(); + foreach (Entries::const_iterator, entries, e) { + *f << e->path; + *f << e->val; + } +} +void +ReadDirReply::Read(FILE*f) +{ + ContentBase::Read(f); + *f >> error; + size_t count; + *f >> count; + entries.resize(count); + while (count) { + count -= 1; + *f >> entries[count].path; + *f >> entries[count].val; + } +} + MSGTYPE(2, ReadReply) ReadReply::~ReadReply() { diff --git a/netfs/msgtypes.h b/netfs/msgtypes.h index 71909cc..0f7b3f0 100644 --- a/netfs/msgtypes.h +++ b/netfs/msgtypes.h @@ -5,6 +5,7 @@ #include "comms.h" #include #include +#include #include #include @@ -117,8 +118,14 @@ class CloseDirRequest : public RequestBase { class ReadDirReply : public ContentBase { public: + class Entry { + public: + std::string path; + struct stat val; + }; + typedef std::vector Entries; int error; - size_t count; + Entries entries; const static uint16_t TypeID; virtual void Send(FILE*) const; virtual void Read(FILE*); @@ -133,15 +140,6 @@ class ReadDirRequest : public RequestBase { virtual void Read(FILE*); }; -class ReadDirContent : public ContentBase { - public: - std::string path; - struct stat val; - const static uint16_t TypeID; - virtual void Send(FILE*) const; - virtual void Read(FILE*); -}; - class OpenReply : public ContentBase { public: int error; -- cgit v1.2.3