<paulproteus> brb yak shaving on vagrant-spk annoyances
jadewang has quit [Remote host closed the connection]
gopar has joined #sandstorm
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 240 seconds]
<paulproteus> The yaks are still hairy )-:
mnutt_ has quit [Quit: mnutt_]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 265 seconds]
<ocdtrekkie> paulproteus: I am happy with the current docs arrangement.
<paulproteus> Wowee!
<paulproteus> Hooray!
<ocdtrekkie> I still like marketplace or bazaar over app store. ;)
<paulproteus> Yeah, I do too actually.
<paulproteus> I think we have to figure out the balance between "internally consistent" and "externally confusing", see also grain vs. file/whatever.
<paulproteus> I think "internally consistent" is pretty OK.
<ocdtrekkie> Mhmm. I just see this desert theme branding here, and then "app store" is like finding a Wal-Mart in the middle of nowhere.
<ocdtrekkie> :P
<ocdtrekkie> I am kinda leaning in favor of saying defining "grain" to people is going to end up worth it.
<ocdtrekkie> And if you only have to explain one term to end users, you're probably still doing pretty well on ease of use.
<paulproteus> Me too.
snolahc1 has joined #sandstorm
itscassaz has joined #sandstorm
aldeka_ has joined #sandstorm
nowhereman has joined #sandstorm
snolahc has quit [Ping timeout: 252 seconds]
itscassa|away has quit [Ping timeout: 252 seconds]
[d__d] has quit [Ping timeout: 252 seconds]
aldeka has quit [Ping timeout: 252 seconds]
nowhere_man has quit [Read error: Connection reset by peer]
[d__d] has joined #sandstorm
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 244 seconds]
itscassaz is now known as itscassa
itscassa is now known as itscassa|away
DanC_ has quit [Ping timeout: 240 seconds]
DanC_ has joined #sandstorm
ecloud_wfh is now known as ecloud
<geofft> is this a reasonable forum for capnp questions, or should I ask on another channel or the mailing list or someting?
<geofft> (I'm still reading, but I expect to have questions to ask tomorrow)
jadewang has joined #sandstorm
gopar has quit [Quit: Leaving]
<kentonv> geofft: This is a great place for capnp questions. :)
jadewang has quit [Remote host closed the connection]
Guest65818 has quit [Quit: http://www.kiwiirc.com/ - A hand crafted IRC client]
Guest65818 has joined #sandstorm
mort___ has joined #sandstorm
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 248 seconds]
ArcTanSusan has joined #sandstorm
nowhere_man_ has joined #sandstorm
nowhereman has quit [Ping timeout: 264 seconds]
jadewang has joined #sandstorm
ArcTanSusan has quit [Quit: ArcTanSusan]
jadewang has quit [Ping timeout: 255 seconds]
babykinggeorge has joined #sandstorm
<babykinggeorge> Going back a few hours, I think the benefits of using 'App Store' in describing Sandstorm and how easy it is (and the link to easily installing apps on your phone) are greater than the benefits of 'Marketplace'
<babykinggeorge> zarvox: If I install the Piwik beta, what happens when you then put it on the App Store - will I have to reinstall it or will it automatically update the beta?
<babykinggeorge> Closing IRC now but will check Logbot later
babykinggeorge has quit [Quit: http://www.kiwiirc.com/ - A hand crafted IRC client]
mort___ has quit [Read error: Connection reset by peer]
mort___ has joined #sandstorm
Guest65818 has quit [Quit: http://www.kiwiirc.com/ - A hand crafted IRC client]
jadewang has joined #sandstorm
mnutt_ has joined #sandstorm
jadewang has quit [Ping timeout: 244 seconds]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 244 seconds]
<geofft> so what's best practice/win 3
<geofft> bah
<geofft> dear brain, please think of one thing at once thanks
<geofft> so what's best practice for authnz for a capnp-rpc server that's ~publicly accessible?
<geofft> I was going to ask last night about how you get capabilities, but it sounds like each server can export a fixed/constant bootstrap capability?
<geofft> should I make a method on that capability that takes a username and password (or something) and returns a real capability?
wat has quit [Quit: a]
<geofft> the second question is going to be, if I'm running over a UNIX socket, is it reasonable to have a "get real cap" method on the bootstrap cap that checks SO_PEERCRED?
<geofft> (and takes no arguments, as far as the capnp-rpc layer knows)
<geofft> or can I do this before issuing the bootstrap cap, or should I be doing something completely different
<dwrensha> geofft: typically a bootstrap interface will have some kind of `restore()` method. The arguments to such a method should be thought of as a "sturdyref" rather than as user credentials.
<dwrensha> where "sturdyref" means "persisted capability"
wat has joined #sandstorm
wat has quit [Quit: a]
wat has joined #sandstorm
itscassa|away is now known as itscassa
wat has quit [Quit: a]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 248 seconds]
<paulproteus> Go figure.
jeffmendoza_ has joined #sandstorm
<paulproteus> kentonv: Whenever you're around, a pseudo-random question: can "spk dev" use 9p aka p9fs rather than FUSE?
<paulproteus> If so, would that improve performance of stat() etc.?
wat has joined #sandstorm
<paulproteus> I guess supposedly it's the context switches, so 9p on the same system might still be super slow.
<paulproteus> I could benchmark with e.g. https://github.com/chaos/diod I suppose.
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 256 seconds]
augustl has quit [Ping timeout: 246 seconds]
jeffmendoza_ has quit [Ping timeout: 265 seconds]
augustl has joined #sandstorm
<paulproteus> Morning, augustl & also everyone else.
<geofft> dwrensha: what's best practice for gaining a sturdyref for the first time / tying to an external login system?
<geofft> (in this case, a UNIX account, either via the kernel for local auth, or PAM or something for remote auth)
<geofft> also I feel like I want to actually use existing authn mechanisms so I don't have to worry about revoking these persisted capabilities
mort___ has quit [Ping timeout: 246 seconds]
<paulproteus> "obviously" store the sturdyref in the user's home directory mode 0600!
<geofft> but they can copy it
<paulproteus> I guess the problem with that is if their account gets deleted, they can keep using the sturdyref presumably, hmm.
<paulproteus> Yeah.
<geofft> like if a user changes their password in /etc/shadow, I expect all existing authn for that account to get revoked
<paulproteus> You could have the sturdyref be a capability to a username verification thing? I don't know, actually, hmm.
<paulproteus> Oh, interesting re: password change => revoke authn
<paulproteus> (this is authz not authn, though, right?)
<geofft> this isn't a problem for e.g. SSH keys 'cause they're asymmetric (having access to the user account doesn't let you persist access)
<geofft> (having access to the client side of SSH does, but that's a different problem)
<geofft> but a capability is a symmetric key / bearer token
<geofft> I think this is authn, "are you this user", not authz, "now that I know you're this user, should you be able to access this"
<geofft> Kerberos has a similar problem, given that it's also a symmetric system -- even if you change your Kerberos password, your tickets are still active
<geofft> but tickets have a lifetime, so the impact of that is limited
<geofft> and I don't think sturdyrefs do?
<paulproteus> The capability could be defined to have a lifetime as interpreted by the object restoring it.
<paulproteus> Maybe that was only 75% comprehensible.
<geofft> right. I don't want to build that myself if there's a best practice for it already :)
<paulproteus> b
<geofft> I mean it sort of feels like I want to build some sort of PAM or OAuth binding into my capnp-rpc protocol, which feels slightly like a mistake
<geofft> I guess the obvious question is, how does Sandstorm handle this? y'all OAuth to GitHub and Google, right?
<geofft> do you marshal OAuth into capnp-rpc?
<paulproteus> As I understand it, we use the OAuth for the Meteor accounts system, and then once the user succeeds at logging in, Meteor.user() == the user in question, and further database queries can use this fact.
<paulproteus> SturdyRefs do separately encode the user identity (e.g. "WebKeys" aka API keys to grains) but that's independent of the OAuth stuff, as I understand it.
<geofft> how do you tie meteor accounts into capabilities? what's the interface there?
<dwrensha> geofft: capabilities have an "owner"
<paulproteus> I think we trust the currently-loged-in user ID when minting the sturdyref, and then the sturdyref remembers the username it was created with.
<dwrensha> if the owner is a user, then that user can restore the capability while logged in through the web interface
<dwrensha> to expose the capability to the outside world, you can save it as a webkey
<dwrensha> "webkey" is the owner
<dwrensha> which means that anyone with the token can restore it
<geofft> if someone steals my Google password, can they restore my capability and then hold onto that capability indefinitely?
<geofft> oh this file is useful to read
<dwrensha> someone logged in as you can only use your capabilities (i.e. those where you are the "owner") as long as they are logged in as you
<geofft> ohhhh. so they're not actually bearer tokens, they need an active login context to work?
<dwrensha> webkeys are bearer tokens
<paulproteus> If it helps (dwrensha correct me if I'm wrong), "webkey" is a sturdyref aka "saved capability"
<dwrensha> paulproteus: not quite
<paulproteus> "restore" means "take a sturdyref and make it a 'live' (online) capability"
<dwrensha> a webkey is a kind of sturdref
<dwrensha> sturdyref
<dwrensha> it's a particular value for the `owner` field
<geofft> but there's a non-bearer-token mode too?
<dwrensha> the `owner` dictates who is allowed to restore the sturdyref
<dwrensha> if it's "webkey", then anyone with the bearer token can restore it
<dwrensha> if it's "user" then only that user can restore it
<geofft> but you have to be constantly holding the "I am this owner" to make use of the restored capability? which, for a webkey, is just a string?
<geofft> but for a user is a user login session?
<geofft> so, the intuitive thing I want is, if I connect over a UNIX socket, I should be able to do stuff as me (the UNIX user) as long as I can be that UID
<geofft> and maybe I should be able to pass capabilities to other people
<dwrensha> sturdrefs can become invalid for a variety of reasons
<geofft> but if I lose the ability to be that UID (e.g. the password is changed and root kills all my processes)
<geofft> both I and anyone I hand capabilities too should no longer be able to do things
<dwrensha> when you restore one that might become invalid, you need to wrap it in a way that will cause the live capability to die appropriately
<dwrensha> to be more concrete, if a sturdyref has some MembraneRequirements, then when it is restored, those requirements need to go into a membrane wrapper
<geofft> if I call a method on that interface that returns a capbility, is that also true of the sub-capabilities?
<dwrensha> that's the distinction between "membrane" and just "wrapper"
<dwrensha> a membrane is transitive
<dwrensha> it propagates itself to subcapabilities
<geofft> ok, I should figure out what a membrane is I guess :)
<dwrensha> we're only just now in the process of implementing them for Sandstorm
<geofft> also before I go further -- is all this in capnproto-rust (or easily implementable) or should I be using C++ for now?
<geofft> yeah, it sounds like I want a UNIX UID membrane or a PAM session membrane or something
<dwrensha> Membranes are not in capnp-rpc-rust. I recommend looking at capnproto-c++.
<geofft> am I gonna hate myself if I try to write a Rust program that uses this (by, like, statically linking a C++ wrapper around my RPC)
<dwrensha> if you're doing fancy stuff with capabilities, I recommend staying away from capnp-rpc-rust for now. It needs some work.
<geofft> hm, I don't think I'm trying to do anything fancy? I could leave off capability passing between multiple users
<geofft> I just want UNIX socket auth
<geofft> which I suppose I could do by checking the ambient SO_PEERCRED authority, even if it's not a particularly clean design
<geofft> and add fancy stuff in the distant future, once y'all are using it in production for Sandstorm :)
mort___ has joined #sandstorm
<dwrensha> geofft: what do you mean by "statically linking a C++ wrapper around my RPC"?
<geofft> write the bulk of my program in Rust, write the stuff that does RPC in C++, statically link them together
<geofft> so I can use capnp-c++ instead of capnp-rust
<dwrensha> ah
<geofft> also, simpler question: if I want to do async push from server to client, does the RPC protocol make this straightforward?
<geofft> can I just have the client send a capability for an interface over, and have the server call it whenever?
<dwrensha> yep, that should be straightforward
<maurer> geofft: if you are only sending one thing to the client, you could just do a regular rpc call and have the client keep it in promise form until it needs it
mnutt_ has quit [Quit: mnutt_]
<maurer> then later when you fulfill the promise, it'd do the async push
<maurer> The "have the client send a callback" will work too though, and makes more sense if there's going to be a steady stream of data
<geofft> yeah, this is for events that can come spontaneously from the server
<paulproteus> i,i like irc
<geofft> I'm writing a protocol for what looks (at the moment) much like screen(1), if that helps contextualize my questions :)
<geofft> output can arrive at any time, and auth should be primarily based on local UNIX UIDs
itscassa is now known as itscassa|away
<maurer> Yeah, I'd probably do something along the lines of sending a "terminal" object to the server
<geofft> so the server can call methods on the interface, and the client's event loop just wakes up whenever anything happens? yup
<geofft> that will work.
<maurer> geofft: well, I haven't looked at the internals of capnproto-c++, but at least in rust's implementation, the way this works is that each interface has its own thread and event loop
<maurer> But the client's main event loop will dispatch to the thread that has the terminal object in it
aldeka_ is now known as aldeka
mnutt__ has quit [Quit: mnutt__]
mort___ has quit [Quit: Leaving.]
jadewang has joined #sandstorm
<kentonv> (catching up) paulproteus: I'd be very surprised if p9fs performed better than FUSE. FUSE does not add any abstractions that p9fs could potentially avoid for better performance. As you say, the problem is context switching.
<kentonv> geofft: I think the discussion of sturdyrefs may not directly address your question
<kentonv> geofft: If you want to authenticate a user, it's up to you to write a Cap'n Proto interface for the authentication you want.
<geofft> kentonv: is there an out-of-the-box one for PAM (or SASL or something)?
<kentonv> geofft: this could be something that has one method that takes a username and password, and returns (if authn succeeded) an authenticated capability
jadewang has quit [Ping timeout: 256 seconds]
<geofft> kentonv: I assume that (in the future?) once I have written an auth mechanism, I can associate the authenticated-ness with other capabilities with membranes?
<geofft> to solve problems like revocation
<kentonv> yes, use membranes for revocation
<kentonv> no, there are no out-of-the-box integrations with any authn system
<kentonv> in general, cap'n proto "doesn't like" authentication since it prefers capability-based design. But you can build authentication protocols on top of capability protocols.
<geofft> is it reasonable to have my bootstrap cap be interface UnixAuth {login @0 () -> (result: SomethingUseful)} that just checks SO_PEERCRED before returning something?
<geofft> where as far as the capnp-rpc layer is concerned there are no parameters, but the UNIX socket is used for auth?
<kentonv> no, here's what you'd do instead:
<kentonv> accept your socket outside of Cap'n Proto. Do your SO_PEERCRED there. Then create a TwoPartyVatNetwork around that socket and give it the already-authenticated capability as the "bootstrap".
<geofft> so don't use ezrpc (directly?) I guess?
<kentonv> you wouldn't want to pull the socket out of Cap'n Proto's RPC layer after the fact and authenticate it in a method call, because that is likely to break Cap'n Proto's security model, especially in the future when three-party introductions ("level 3" RPC) are a thing
<geofft> gotcha
<kentonv> since some day Alice will be able to give Bob a capability to Carol, and then Bab and Carol will directly connect, but if Bob or Carol is checking SO_PEERCRED to decide what capabilities on that connection can do, then you'll have lots of confused deputy problems where Alice can trick Bob and Carol into doing things with each other's caps that Alice can't do directly
<kentonv> similar to the Linux vulnerabilities where some kinds of FDs do authentication on write() rather than open(), which leads to problems when you pass those capabilities as stdio on a suid program.
<kentonv> those FDs I mean
<geofft> oh sure. yes.
<geofft> right, I guess you want to distinguish "I am opening this UNIX socket because I have this capability I hear I can use" from "I am opening this UNIX socket so that you can authenticate me and give me a capability"
<geofft> and the latter should be very explicit
<kentonv> yeah
<geofft> yeah, I'm not used to thinking in terms of capability tokens themselves as capabilities, just open file descriptors as capabilities :)
<kentonv> personally I would prefer to avoid designs based on SO_PEERCRED but I don't want to tell you how to design your software. :)
<geofft> could also SCM_CREDENTIALS to make it more explicit, sure.
<geofft> I mean, I want local users to be able to connect to their own server, but I also sort of want them to be able to delegate access to other UNIX users
<kentonv> I'm saying I'd avoid any design based on checking the UID of the calling process. :)
<geofft> hrrm. how would you give the user a way to talk to their own server?
<kentonv> but admittedly depending on the context that may be going against the grain too much
<geofft> like how do you implement `screen -r`? store a capability in the filesystem and let filesystem ownership checks take care of it?
<geofft> that feels worse, though I can't quite express how.
<geofft> also if I want to do something like give paulproteus access to my screen session, I'd rather tell my app "give paulproteus access", not "give me a token that I can copy/paste to him"
<geofft> as a UX thing
<geofft> but maybe I'm wrong and there's a better UX for this?
<kentonv> well let's see...
<kentonv> I think when you create the screen session, you get a capability to it. Abstractly, you can pass that capability to others.
<kentonv> but a capability isn't necessarily a bit string
<kentonv> I think a lot of the discomfort with capabilities comes from implementations where they are just bit strings
<kentonv> in Cap'n Proto, sturdyrefs are bit strings, BUT a sturdyref is sealed to a particular creator identity who is the only one that can restore it
<kentonv> only *live* object refs can be passed around
<kentonv> so then you pass the life ref to paulproteus and he calls save() on it to get his own sturdyref
<kentonv> meanwhile, the server tracks who has saved it, giving you the ability to revoke those saves
<geofft> is there a way to take the sturdyref out of it, so that paulproteus can just run `screen -list` or `screen -r geofft` without me having to send him anything?
<kentonv> how does he know he can do that if you haven't sent him anything?
<geofft> mmm. his client talks to /var/run/screen/S-geofft and figures out that he has been granted access?
<kentonv> but why would he, as a human, look for that, if you haven't said anything to him? :)
<geofft> oh fine. because I say "hey, go run screen -r geofft"
<kentonv> heh
<kentonv> so in the ideal, somehow a capability would be embedded in your sentence. That's obviously not possible in actual vocal speech, though.
<kentonv> so now we get into what Sandstorm does, on top of Cap'n Proto
<geofft> yeah, it is true that if I say this over IM, I can say "hey, go run screen -r 5b5a5761b70d89369c60bd32` or whatever
<kentonv> well ideally your IM client would be capability-aware so that it could actually send a live ref rather than a bit string
<kentonv> but that is, again, probably not realistic anytime soon
<geofft> ideally lots of things, lemme get rid of termios first then we can talk about capability-aware IM clients :P
<kentonv> so Sandstorm implements user accounts, but a user account is really just a bag of capabilities
<kentonv> in an ideal capability-based server environment, you'd share your screen session to paulproteus by sending the capability to his user account (capability bag)
<kentonv> and then he'd be able to access it ambiently
<geofft> yeah, I think part of the friction here is that, if I'm thinking about just UNIX, there isn't a great way to do that.
<kentonv> right
<geofft> if there's a web server or something, sure, now there's a shared daemon that we both connect to that can handle passing capabilities between us
<geofft> (and I should keep that in mind)
<kentonv> some day this could be mediated through Sandstorm, since Sandstorm will be good at importing arbitrary capnp capabilities pointing at external servers
<kentonv> until then, yeah, you may need to do something non-capability-based
<geofft> but if we're talking about a single isolated UNIX server on an intranet, then I'd need to check UNIX accounts
<geofft> and as far as possible I'd like to hand that job off to e.g. SSH and use UNIX UIDs
<geofft> although I could have a single privileged server that runs PAM
<kentonv> yeah, I think you should probably do what you were planning to do.
<geofft> ok, it sounds like I should not deeply bake in the concept of UNIX accounts for auth, but it's fine to have an explicit bootstrap service that authenticates UNIX sockets
<kentonv> but it still makes me uncomfortable since so often ambient authority leads to problems
<geofft> I may do SCM_CREDENTIALS instead of SO_PEERCRED just to make sure that you have to explicitly say "please treat me as the UNIX user I am"
<kentonv> consider for example that every sandstorm app runs with the UID of the server owner, even though they clearly aren't supposed to have the server owner's authority. But OTOH they aren't going to be able to make unix socket connections to outside of the sandbox, so it's probably ok?
<geofft> eugh
<geofft> so, what stops them from ptracing outside the sandbox?
<kentonv> a few things
<geofft> or editing ~/.ssh/authorized_keys, or whatnot
<kentonv> (1) ptrace is disabled via seccomp
<kentonv> (2) they are in a pid namespace, can't address outside pids
<kentonv> (3) they are in a mount namespace, cannot see any part of the filesystem they aren't supposed to
<geofft> I _think_ it's reasonable for me to assume that anyone who's implementing a "keep the same UID, have less authority" system is doing those sorts of things?
<geofft> like you said, they can't physically make connections outside the sandbox so it's ok?
<kentonv> probably, yes
<kentonv> that is to say, it would be a bug in Sandstorm, not your code
<geofft> right.
<geofft> maybe it makes sense to have a paranoid mode, where you can disable your own UNIX user's access to your screen session
<geofft> so you can only get into it via previously-issued capabilities
<geofft> which would be easy to do if I don't bake UNIX auth in.
<geofft> (hm, this feels a bit like X11 .Xauthority / magic cookie to localhost vs. unix: auth)
<kentonv> "paranoid mode" would also allow participating in the capability fabric with 3-party introductions etc., so it's more than just "paranoid".
<kentonv> I guess I'd call it "capability mode"
<kentonv> but for your immediate needs, this is perhaps a non-goal
<geofft> yeah, I wouldn't call it "paranoid", just say that by default, in addition to capabilities, there's a UNIX UID ACL containing yourself
<geofft> but you can add UIDs to ACLs, or you can remove yourself and just use capabilities
<geofft> and if you don't intend to use the CLI client, you should perhaps take yourself off the ACL
<kentonv> I suppose people could potentially bootstrap from unix mode to capability mode by doing a save()/restore()
<kentonv> the restore would be over a non-uid-aware connection, so then it's safe to do 3-party introductions from there
<geofft> yeah, that's an option -- have a separate socket in the filesystem for "auth me with my UNIX UID" vs. "I just want to talk RPC, I've got a capability already"
<kentonv> that seems pretty reasonable actually
<kentonv> hmmmmm
<paulproteus> BTW I <3 that I see messages in scrollback like
<kentonv> are you using 0.5.x or git master?
<paulproteus> "so then you pass the life ref to paulproteus and he calls save() on it to get his own sturdyref"
<paulproteus> It's like I'm Alice or Bob except I'm Asheesh : D
<kentonv> geofft: In master I've introduced a concept called `BootstrapFactory` which allows you to grant different bootstraps to different clients based on authentication of the underlying connection. It's designed to allow you to bootstrap off of cryptographic authentication already done at the transport layer.
<kentonv> geofft: but I think a transport based on unix sockets could just substitute the unix credentials in place of crypto auth
<kentonv> geofft: although this depends on a "unix VatNetwork" implementation that doesn't exist currently.
<XgF> On a "Unixy network" (Kereros auth) you could probably use kerberos tickets to auth the user
<XgF> On Windows you can actually get "protected capabilities" which the OS will protect in a similar manner to kentonv discussed for sandstorm
<kentonv> geofft: this pattern (where *only* the bootstrap capability is based on external auth) maxes it safe to participate in multi-party networks with introductions, since no individual method call checks the UID of the caller at call time.
<XgF> kentonv: And I guess "membranes" come in for distinguishing a "Document" I have write access to vs one I can only read?
<kentonv> XgF: Membranes are primarily for revocability.
<kentonv> for things like read vs. write you'd usually use "just" a wrapper
<XgF> OK. With that kind of stuff I always worry about loops in the objetc graph causing escapes :)
<kentonv> the difference being that a membrane also wraps all capabilities introduced through it, whereas a wrapper focuses on wrapping just the first-level capability
<kentonv> ah
<kentonv> well I think it depends on the interface you're working with
<XgF> e.g. a document which contains a subdocument which contains a parent reference...
<kentonv> parent references are not capability-friendly in general
<kentonv> because what if you want to give access just to the subdocument?
<kentonv> so I think in a good capability design you'd avoid that
jadewang has joined #sandstorm
<XgF> kentonv: "Where" does the document live, though? (I.E. how do you decide when it can be freed?) :-)
<kentonv> if the client needs to know the document's full path, then the client should be passed a list of capabilities representing the full path. No need for parent pointers then.
<kentonv> in fact you can see this problem illustrated in the way ".." work on unix
<kentonv> in almost all cases, you actually don't want the filesystem's "..", you want to remove the last element from the preceding path.
<kentonv> the two cases being different when the preceding element is a symlink
<kentonv> and $PWD is how we tell processes "here's the list of parent directories of the current directory"
<kentonv> so that they don't have to follow ..
jadewang has quit [Ping timeout: 244 seconds]
<kentonv> I wish we could remove ".." from filesystems and instead say that it's userspace's job to process it.
<kentonv> then we could pass people directory FDs and know that they can't just jump out to the parent.
<kentonv> oh man, now I want to write a KJ filesystem API based on this concept.
<paulproteus> Hey so kentonv does p9fs solve our fuse performance problems?
<paulproteus> (That is have you considered it/benchmarked things/etc.)
<paulproteus> I don't know if you have, but I thought I'd at least ask.
<kentonv> I don't see how it could.
<kentonv> FUSE is as low-level as it gets...
<paulproteus> The time is lost in context switches? If so, yeah, hmmph.
<kentonv> FUSE is essentially the kernel filesystem interface expressed as a socket protocol
<kentonv> well I suppose there's a possibility that p9fs can avoid a network round trip (context switch, in our case) to stat() a file that it already knows doesn't exist based on previously having fetched a listing of the directory. But I think it's relatively unlikely that it does that.
<paulproteus> p9fs does have a stat cache in the kernel, from what I can tell, configured with a cache duration as a mount option
<paulproteus> Let me look that up.
<geofft> kentonv: I can use whatever, I'm using 0.5.2 from Debian + capnp*-rust from git
<kentonv> paulproteus: stat caching is normal. But caching directory listings in order to quickly resolve stats on *new* paths that don't exist is unusual.
<paulproteus> Yeah, hmm, right. I think I wrote an LD_PRELOAD for something like that late one night while procrastinating going to sleep before a wedding.
<paulproteus> Whatever I did gave me only a ~10% improvement in a synthetic stat benchmark so I didn't talk about it much.
<kentonv> that's.... interesting....
<kentonv> hmm
<kentonv> that could probably fix ruby
<paulproteus> I wonder if NFS is this slow for Rails, too. If so, waah how do the Rails people deal.
<kentonv> basically the proposal is: whenever stat()ing a file in a directory we haven't seen yet, actually list the directory, cache that, and then use that cache to early-return from stat() calls for files that don't exist going forward.
<paulproteus> Ya.
<paulproteus> Not sure exactly what to do about invalidation.
<paulproteus> Also we could "just" make this into a kernel module!!
<kentonv> I actually think it's way better in userspace
<kentonv> more secure, and avoids syscall overhead
<kentonv> no need for invalidation -- the filesystem is static.
<kentonv> at least in the Sandstorm case
<kentonv> (don't apply the optimization for paths under /var)
<paulproteus> Right, yeah.
<paulproteus> You can do better than that.
<paulproteus> You can store the entire file list of / in the LD_PRELOAD's memory and if the file doesn't exist, don't do a real stat, return a simulated stat.
<paulproteus> Now that I think about it, iirc that's what I was doing.
<kentonv> you could use a bloom filter!
<paulproteus> You could use a Markov chain!
<paulproteus> (kidding!)
<kentonv> I'm serious, though: As part of the build, create a bloom filter of sandstorm-files.list and include that in the package, then optimize stat() based on that. Super-efficient.
<kentonv> oh but that wouldn't help with dev mode
<paulproteus> Yeah, I'm reading https://en.wikipedia.org/wiki/Bloom_filter and agreeing with you, in all seriousness.
<geofft> do your syscall overheads get smaller if you make an effort to put the client and the FUSE server on different cores?
<kentonv> geofft: we'll they're separate processes so the kernel should be taking care of that already...
<kentonv> but actually I would think that you want them on the same core since they're synchronous
<kentonv> there's really no opportunity for parallelism
<geofft> I somehow assumed that inter-processor overhead is smaller than context switch (MMU invalidation) overhead
<geofft> but I guess there's no particular reason to believe that
<paulproteus> kentonv: re: store a bloom filter: That basically work for dev mode, if it were an LD_PRELOAD, right?
<paulproteus> geofft: FWIW my hunch is the same as yours, though I've surely done less low level muckery than you or kentonv.
<paulproteus> I guess you have to create a files list with lots of readdir() or whatever, which would add to 'spk dev' startup time.
<kentonv> paulproteus: the problem is you don't know what to put into the bloom filter because it's the whole point of the FUSE layer to determine that...
<paulproteus> o
<paulproteus> Right.
<geofft> I'm moderately curious what the problem statement is here (is there a GitHub issue?)
<paulproteus> But you could still prove the nonexistence of files.
<geofft> but I could go back to writing my capnp-rpc protocol for my screen knockoff
<kentonv> paulproteus: are you going to enumerate the user's ENTIRE filesystem in advance? I could see it working if we restrict it to just the ruby package paths, though.
<kentonv> geofft: Ruby startup is O(n^2) in number of dependencies.
<paulproteus> Yeah, presumably 'spk dev' could have some heuristic where if one dir tree is stat'd more than N times, then it does the aggressive listing to minimize stats.
<kentonv> geofft: because for every require() call, they search for the path in _every_ dependency package, leading to a lot of stat()s returning ENOENT.
mattl has quit [Excess Flood]
mattl has joined #sandstorm
<geofft> ... price doesn't have something magical for this?
<geofft> also does the kernel side of FUSE not cache negative directory entries?
<paulproteus> I think price's stuff was only for memory usage, not decreasing stats.
<paulproteus> Well CPU time related to the Ruby GC.
<kentonv> paulproteus: ehh, I'd kind of like to build the bloom filter upfront, like actually outside of the sandbox. Perhaps you could specify "problem directories" in your bridge config and `spk dev` would generate a bloom filter based on that...
<geofft> right, but I wonder if hooking something into Ruby is a better solution here
<geofft> NFS, I'm pretty sure, _does_ do negative dentry caching
<kentonv> geofft: negative caching doesn't help because it's a new path every single time
<paulproteus> i,i maybe we can "just" port spk dev to NFS
<geofft> kentonv: ohhhh ok
<kentonv> geofft: you would have to not just negatively cache, but actually cache entire directory listings so that you can tell in advance that a file isn't present.
<paulproteus> FWIW the vagrant-spk Rails stack can have whatever hackery we need in the default bridgeConfig it creates, or whatever.
<kentonv> the Linux (Unix?) filesystem model seems to be designed with the assumption that directory listings aren't necessarily complete
jleo has quit [Ping timeout: 255 seconds]
<geofft> yeah, I guess /proc and stuff relies on that
<kentonv> geofft: out of curiosity, what directory in /proc has an incomplete listing?
jleo has joined #sandstorm
<geofft> /proc itself -- you can access any thread via /proc/$pid, but only threads that are threadgroup leaders (i.e., processes) show up
<kentonv> ah
<kentonv> didn't know that
<paulproteus> That is kind of hilarious.
<geofft> also automounters, but that's a somewhat specialized use case
<paulproteus> Semi-ingenious, semi ridiculous layering violation.
<geofft> is there anything for getters/setters on interfaces or do I just make my own getFoo @0 () -> (foo: Foo) and setFoo @1 (foo: Foo)?
<kentonv> geofft: You make your own. (I've actually found it pretty rare to want getters/setters on interfaces personally.)
* paulproteus debugs Vagrant + Debian + virtualbox + Windows stuff
<dwrensha> ping jparyani
<kentonv> I think he's on vacation today
<paulproteus> Yeah, I saw the build fail dwrensha .
<paulproteus> w/r/t email sending
<dwrensha> it also failed a sharing test
<dwrensha> I'm wondering whether grains are deleted between the test cases
<dwrensha> if not, that would explain it
<dwrensha> because you won't get the incognito interstitial the second time
<kentonv> hmm were these tests not tried locally?
<dwrensha> I did not run the tests locally
<dwrensha> I'll look into fixing up the testcases
<kentonv> ok, thanks
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 260 seconds]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 265 seconds]