Beispiel #1
0
// XXX could ideally try to find the newest version over
//     all replicas and move that everywhere.
//     This ought to do that eventually...
void
dhblock_keyhash_srv::real_repair (blockID key, ptr<location> me, u_int32_t *myaux, ptr<location> them, u_int32_t *theiraux)
{
  // keyhash aux is the version number of the block.
  ptr<location> s = NULL; // We calculate our own source?
  ptr<repair_job> job;
  if (!myaux) {
    // We're missing, so fetch it.
    job = New refcounted<rjrep> (key, s, me, mkref (this));
    repair_add (job);
  } else {
    // They're missing so push it.
    // Otherwise, move towards the newer one.
    if (!theiraux) {
      job = New refcounted<rjrep> (key, s, them, mkref (this));
      repair_add (job);
    } else if (*theiraux < *myaux) {
      job = New refcounted<rjrep> (key, s, them, mkref (this));
      repair_add (job);
    } else if (*theiraux > *myaux) {
      job = New refcounted<rjrep> (key, s, me, mkref (this));
      repair_add (job);
    }
  }
}
Beispiel #2
0
void 
unixfd::rcb ()
{
  if (reof) {
    fdcb (localfd_in, selread, NULL);
    return;
  }

  char buf[16*1024];
  int fdrecved = -1;
  ssize_t n;
  if (unixsock)
    n = readfd (localfd_in, buf, sizeof (buf), &fdrecved);
  else
    n = read (localfd_in, buf, sizeof (buf));

  if (n < 0) {
    if (errno != EAGAIN)
      abort ();
    return;
  }

  if (!n) {
    readeof ();
    return;
  }
  else {
    rex_payload arg;
    arg.channel = channo;
    arg.fd = fd;
    arg.data.set (buf, n);

    if (fdrecved >= 0) {
      close_on_exec (fdrecved);
      rex_newfd_arg arg;
      arg.channel = channo;
      arg.fd = fd;
      ref<rex_newfd_res> resp (New refcounted<rex_newfd_res> (false));
      proxy->call (REX_NEWFD, &arg, resp,
		   wrap (mkref (this), &unixfd::newfdcb, fdrecved, resp));
    }

    ref<bool> pres (New refcounted<bool> (false));
    rsize += n;
    proxy->call (REX_DATA, &arg, pres,
		 wrap (mkref (this), &unixfd::datacb, n, pres));
  }

  if (rsize >= hiwat)
    fdcb (localfd_in, selread, NULL);
}
Beispiel #3
0
afsdirentry::afsdirentry (afsdir *dir, const str &name, afsnode *node)
  : dir (dir), name (name), node (mkref (node)), cookie (gencookie ())
{
  node->addlink ();
  cookietab.insert (this);
  dir->entries.insert (this);
}
Beispiel #4
0
void
aios::input ()
{
  if (rlock)
    return;
  rlock = true;

  ref<aios> hold = mkref (this); // Don't let this be freed under us

  int n = ::readv (fd, const_cast<iovec *> (inb.iniov ()), inb.iniovcnt ());
  if (n > 0)
    inb.addbytes (n);
  else if (n < 0 && errno != EAGAIN) {
    fail (errno);
    rlock = false;
    return;
  }
  else if (!n && !(this->*infn) ()) {
    fail (0);
    rlock = false;
    return;
  }
  while ((this->*infn) ())
    ;
  if (fd >= 0) {
    if (rcb)
      fdcb (fd, selread, wrap (this, &aios::input));
    else
      fdcb (fd, selread, NULL);
    //timeoutbump ();
  }
  rlock = false;
}
Beispiel #5
0
ref<sfsserver_auth::userauth>
sfsserver_auth::userauth_alloc (sfs_aid aid)
{
  ref<userauth> uap (New refcounted<userauth> (aid, mkref (this)));
  uap->sendreq ();
  return uap;
}
Beispiel #6
0
void
afsusrroot::nfs_lookup (svccb *sbp, str name)
{
  afsnode *e = lookup (name, aid);
  if (e) {
    if (int err = srvinfo::geterr (name))
      nfs_error (sbp, err);
    else
      lookup_reply (sbp, e);
    return;
  }
  else if ((!sfs_parsepath (name)
	    && (!namedprotrx.match (name) /*|| !nptab[namedprotrx[1]]*/))
	   || terminating) {
    nfs_error (sbp, ENOENT);
    return;
  }

  ref<delaypt> dpt = delaypt::alloc ();
  ref<setupstate> ss = New refcounted<setupstate> (name, dpt);
  link (dpt, name);

  if (ptr<aclnt> ch = agentc ())
    ch->timedcall (agent_timeout, AGENTCB_REVOKED, &name, &ss->revres,
		   wrap (mkref (this), &afsusrroot::revcb, ss));
  else {
    ss->revdone = true;
    finish (ss, NFS_OK);
  }

  lookup_reply (sbp, afsdir::lookup (name, aid));
}
Beispiel #7
0
void
aios::output ()
{
  ref<aios> hold = mkref (this); // Don't let this be freed under us
  suio *out = outb.tosuio ();

  int res;
  if (fdsendq.empty ())
    res = out->output (fd);
  else {
    int cnt = out->iovcnt ();
    if (cnt > UIO_MAXIOV)
      cnt = UIO_MAXIOV;
    res = writevfd (fd, out->iov (), cnt, fdsendq.front ());
    if (res > 0) {
      out->rembytes (res);
      ::close (fdsendq.pop_front ());
    }
    else if (res < 0 && errno == EAGAIN)
      res = 0;
  }
      
  if (res < 0) {
    fail (errno);
    return;
  }
  if (res > 0)
    timeoutbump ();
  if (weof && !out->resid ())
    shutdown (fd, SHUT_WR);
  wblock = !res;
  setoutcb ();
}
Beispiel #8
0
rexfd::rexfd (rexchannel *pch, int fd)
  : pch (pch), proxy (pch->get_proxy ()), channo (pch->get_channo ()),
    fd (fd)
{
/*   warn << "--reached rexfd\n"; */
  if (fd < 0)
    fatal ("attempt to create negative fd: %d\n", fd);
  pch->insert_fd (fd, mkref (this));
}
Beispiel #9
0
void 
vnode_impl::get_predecessor (ptr<location> n, cbchordID_t cb)
{
  ptr<chordID> v = New refcounted<chordID> (n->id ());
  ngetpredecessor++;
  chord_noderes *res = New chord_noderes (CHORD_OK);
  doRPC (n, chord_program_1, CHORDPROC_GETPREDECESSOR, v, res,
	 wrap (mkref (this), &vnode_impl::get_predecessor_cb, n->id (), cb, res));
}
Beispiel #10
0
void
vnode_impl::get_succlist (ptr<location> n, cbchordIDlist_t cb)
{
  ngetsucclist++;
  chord_nodelistres *res = New chord_nodelistres (CHORD_OK);
  ptr<chordID> v = New refcounted<chordID> (n->id ());
  doRPC (n, chord_program_1, CHORDPROC_GETSUCCLIST, v, res,
	 wrap (mkref (this), &vnode_impl::get_succlist_cb, cb, res));
}
Beispiel #11
0
void 
vnode_impl::get_successor (ptr<location> n, cbchordID_t cb)
{
  //  warn << "get successor of " << n << "\n";
  ngetsuccessor++;
  chord_noderes *res = New chord_noderes (CHORD_OK);
  ptr<chordID> v = New refcounted<chordID> (n->id ());
  doRPC (n, chord_program_1, CHORDPROC_GETSUCCESSOR, v, res,
	 wrap (mkref (this), &vnode_impl::get_successor_cb, n->id (), cb, res));
}
Beispiel #12
0
void
afsusrroot::finish (ref<setupstate> ss, int err)
{
  if (!ss->dpt)
    return;
  if (!err)
    err = srvinfo::geterr (ss->name);
  if (err) {
    ss->dpt->setres (nfsstat (err));
    ss->dpt = NULL;
    delaycb (15, wrap (afsdir_unlink, mkref (this), ss->name));
    return;
  }
  if (!ss->revdone)
    return;

  afsnode *e = lookup (ss->name, NULL);
  if (!e || e == ss->dpt)
    e = afs_sfsroot->lookup (ss->name, NULL);

  if (e) {
    str name = ss->name;
    unlink (name);
    link (e, name);
#if FIX_MNTPOINT
    if (opt_fix_mntpoint) {
      if (str res = e->readlink ())
	ss->dpt->setres (res);
      else {
	warn << "afsusrroot::finish: shouldn't get here (please report bug)\n";
	ss->dpt->setres (strbuf ("%s/%s", sfsroot, ss->name.cstr ()));
	ss->dpt->setres (strbuf ("%s/" MPDOT "%s/r", sfsroot,
				 ss->name.cstr ()));
      }
    }
    else
#endif /* FIX_MNTPOINT */
      ss->dpt->setres (strbuf ("%s/%s", sfsroot, ss->name.cstr ()));
  }
  else
    srvinfo::alloc (ss->name, wrap (mkref (this), &afsusrroot::finish, ss));
}
Beispiel #13
0
    void ping_start() {
	if (self_.mid == view_.primary.mid) {
	    ping_incoming_.clear();
	    ping_timeout_cb_ =
		delaycb(periodic_primary_ping + timeout_primary_ping,
			wrap(mkref(this), &cohort::ping_check_incoming));
	} else {
	    ping_timeout_cb_ =
		delaycb(periodic_primary_ping,
			wrap(mkref(this), &cohort::ping_start));
	}

	ping_arg arg;
	arg.myid = self_.mid;
	arg.vid = view_.vid;
	sockaddr_in sin = netaddr2sockaddr(view_.primary.addr);
	ref<ping_res> resp = New refcounted<ping_res>();
	c_->timedcall(timeout_primary_ping, REP_PING, &arg, resp,
		      wrap(mkref(this), &cohort::ping_cb, view_.vid, resp),
		      0, 0, 0, 0, 0, (sockaddr *) &sin);
    }
Beispiel #14
0
void
vnode_impl::alert (ptr<location> n, ptr<location> x)
{
  ptr<chord_nodearg> na = New refcounted<chord_nodearg>;
  chordstat *res = New chordstat;
  nalert++;
  warnx << "alert: " << x->id() << " died; notify " << n->id () << "\n";
  x->fill_node (na->n);

  doRPC (n, chord_program_1, CHORDPROC_ALERT, na, res, 
	 wrap (mkref (this), &vnode_impl::alert_cb, res));
}
Beispiel #15
0
void
vnode_impl::notify (ptr<location> n, chordID &x)
{
  ptr<chord_nodearg> na = New refcounted<chord_nodearg>;
  chordstat *res = New chordstat;
  nnotify++;
  // warnx << gettime () << ": notify " << n << " about " << x << "\n";
  locations->lookup (x)->fill_node (na->n);
  
  doRPC (n, chord_program_1, CHORDPROC_NOTIFY, na, res, 
	 wrap (mkref (this), &vnode_impl::notify_cb, n->id (), res));
}
Beispiel #16
0
int
aios::flush ()
{
  ptr<aios> hold;
  if (fd >= 0 && outb.tosuio ()->resid ()) {
    hold = mkref (this);	// Don't let this be freed under us
    make_sync (fd);
    output ();
    _make_async (fd);
  }
  return err;
}
Beispiel #17
0
void
asrv::seteof (ref<xhinfo> xi, const sockaddr *src, bool force)
{
    if (force || xi->xh->connected) {
        asrv *s;
        ptr<asrv> sp;
        for (s = xi->stab.first (); s; s = xi->stab.next (s)) {
            sp = mkref (s);
            if (s->cb)
                (*s->cb) (NULL);
        }
    }
}
Beispiel #18
0
void
chord::tcpclient_cb (int srvfd)
{
  int fd = accept (srvfd, NULL, NULL);
  if (fd < 0)
    warn << "chord: accept failed " << strerror (errno) << "\n";
  else {
    ptr<axprt> x = axprt_stream::alloc (fd, 230000);

    ptr<asrv> s = asrv::alloc (x, transport_program_1);
    s->setcb (wrap (mkref(this), &chord::dispatch, s));
  }
}
Beispiel #19
0
void
svccb::init (asrv *s, const sockaddr *src)
{
    srv = mkref (s);
    srv->xi->svcadd ();
    if (!s->xi->xh->connected) {
        addrlen = s->xi->xh->socksize;
        addr = (sockaddr *) opnew (addrlen);
        memcpy (addr, src, addrlen);
    }

    // keep track of when this RPC started
    ts_start = sfs_get_tsnow();
}
Beispiel #20
0
  void start () {
    char tfile[80];
    sprintf (tfile, "aio.%02d~", fctr++);
    path = tfile;
    str msg ("This is " << path << ".\n");
    buf = a->bufalloc (msg.len () + 1);
    if (!buf) {
      a->bufwait (wrap (this, &aiotst::start));
      return;
    }
    strcpy (buf->base (), msg);
    a->open (path, O_CREAT|O_RDWR|O_TRUNC, 0666,
	     wrap (mkref (this), &aiotst::opencb));
    a->finalize ();
  }
Beispiel #21
0
void
client::rmdircb_1 (svccb *sbp, void *_res, lookup3res *lres, 
                   filesrv::reqstate rqs,
		   ptr<acltargetlist> targets, clnt_stat err)
{
  AUTH *auth = auth_sfs;

  if (err || !lres || lres->status || !auth) {
    warn << "RMDIR: failed because LOOKUP failed\n";
    reject_nfs (sbp, targets, NFS3ERR_SERVERFAULT);
    if (lres)
      delete lres;
    return;
  }

  ptr<nfs_fh3> fhp = New refcounted<nfs_fh3>;
  if (!get_lookupresfh (lres, fhp)) {
    warn << "RMDIR: Failed to get fh for the dir we're deleting.";
    delete lres;
    reject_nfs (sbp, targets, NFS3ERR_SERVERFAULT);
    return;
  }
  if (lres->resok->obj_attributes.present
      && lres->resok->obj_attributes.attributes->type != NF3DIR) {
    warn << "RMDIR: Lookup did not return a fh for a directory\n";
    delete lres;
    reject_nfs (sbp, targets, NFS3ERR_SERVERFAULT);
    return;
  }

  // this is a workaround wrap()'s 7 argument limitation
  ref<sbpandres> sr = New refcounted<sbpandres>;
  sr->sbp = sbp;
  sr->res = _res;

  readdir3args readdirargs;
  readdirargs.dir = *fhp;
  readdirargs.cookie = 0;
  readdirargs.count = 8192;

  readdir3res *rres = New readdir3res;
  rqs.c->call (NFSPROC3_READDIR, &readdirargs, rres,
	       wrap (mkref (this), &client::rmdircb_2,
		     sr, rres, fhp, rqs, targets), 
	       auth);

  delete lres;
}
Beispiel #22
0
void 
client::aclresolve_type (svccb *sbp, filesrv::reqstate rqs,
			 ptr<acltargetlist> targets)
{
  acltarget *entry = targets->next_entry (); 
  assert (entry);
  assert (entry->get_objecttype () == unknown);
  
  nfs_fh3 *args =  entry->get_objectfhp (); 
  getattr3res *res = New getattr3res; 
  
  rqs.c->call (NFSPROC3_GETATTR, args ,res, 
	       wrap (mkref (this), &client::aclresolve_type_cb, sbp, rqs, res,
		     targets), 
	       auth_sfs);
}
Beispiel #23
0
void
chord::startchord ()
{
  assert (fd_stream > 0 || fd_dgram > 0);
  if (fd_dgram > 0) {
    x_dgram = axprt_dgram::alloc (fd_dgram, sizeof(sockaddr), 230000);
    ptr<asrv> s = asrv::alloc (x_dgram, transport_program_1);
    s->setcb (wrap (mkref(this), &chord::dispatch, s));
  }

  if (fd_stream > 0) {
    int ret = listen (fd_stream, 1000);
    if (ret < 0)
      fatal ("listen (%d, 1000): %m\n", fd_stream);
    fdcb (fd_stream, selread, wrap (this, &chord::tcpclient_cb, fd_stream));
  }
}
Beispiel #24
0
void
client::rmdircb_2 (ptr<sbpandres> sr, readdir3res *rres,
                   ptr<nfs_fh3> fhp, filesrv::reqstate rqs,
                   ptr<acltargetlist> targets, clnt_stat err)
{
  AUTH *auth = auth_sfs;

  if (err || !rres || rres->status || !auth) {
    warn << "RMDIR: failed because READDIR failed\n";
    reject_nfs (sr->sbp, targets, NFS3ERR_SERVERFAULT);
    if (rres)
      delete rres;
    return;
  }

  int n = 0;
  entry3 *ep = rres->resok->reply.entries;
  if (ep)
    for (;;) {
      n++;
      entry3 *nep = ep->nextentry;
      if (!nep)
	break;
      ep = nep;
    }

  // assume that 3 means ".", "..", and ".SFSACL"
  if (n > 3) {
    warn << "RMDIR: directory isn't empty\n";
    reject_nfs (sr->sbp, targets, NFS3ERR_NOTEMPTY);
    delete rres;
    return;
  }

  diropargs3 removeargs;
  removeargs.dir = *fhp;
  removeargs.name = SFSDIRACL;

  wccstat3 *wres = New wccstat3;
  rqs.c->call (NFSPROC3_REMOVE, &removeargs, wres,
	       wrap (mkref (this), &client::rmdircb_3,
		     sr->sbp, sr->res, wres, rqs, targets), 
	       auth);

  delete rres;
}
Beispiel #25
0
void
axprt_dgram::input ()
{
  ref<axprt> hold (mkref (this)); // Don't let this be freed under us
  for (size_t tot = 0; cb && tot < pktsize;) {
    socklen_t ss = socksize;
    bzero (sabuf, ss);
    ssize_t ps = recvfrom (fd, pktbuf, pktsize, 0, sabuf, &ss);
    if (ps < 0) {
      if (errno != EAGAIN && connected)
	(*cb) (NULL, -1, NULL);
      return;
    }
    tot += ps;
    (*cb) (pktbuf, ps, sabuf);
  }
}
Beispiel #26
0
afsnode *
afsusrdir::lookup (const str &name, sfs_aid rqaid)
{
  if (afsnode *n = afsdir::lookup (name, aid))
    return n;
  ptr<aclnt> ch;
  if (negcache[name] || !nameok (name) || !(ch = agentc ()))
    return NULL;

  ref<delaypt> dpt = delaypt::alloc ();
  link (dpt, name);
  sfs_filename lname = path ? str (path << "/" << name) : name;
  ref<sfsagent_lookup_res> resp = New refcounted<sfsagent_lookup_res>;
  ch->timedcall (agent_timeout, AGENTCB_LOOKUP, &lname, resp,
		    wrap (mkref (this), &afsusrdir::lookup_cb,
			  name, dpt, resp));
  return dpt;
}
Beispiel #27
0
//after mkdir, we must write the new dir's acl
//first, create the new file and in create_diracl_cb
//if creation worked, use write_acl (as in the case of newly-created file)
//to write the acl
void
client::create_diracl (svccb *sbp, void *res, filesrv::reqstate rqs, 
		       ptr<acltargetlist> targets, nfs_fh3 fh)
{
  create3args cargs;
  diropres3 *cres = New diropres3;

  cargs.where.dir = fh;
  cargs.where.name = SFSDIRACL;
  cargs.how.set_mode (UNCHECKED);

  cargs.how.obj_attributes->mode.set_set (true); 
  *cargs.how.obj_attributes->mode.val = CREATEACL_MODE;

  rqs.c->call (NFSPROC3_CREATE, &cargs, cres,
	       wrap (mkref (this), &client::create_diracl_cb, 
		     sbp, res, rqs, targets, cres),
	       auth_sfs);  
}
Beispiel #28
0
//we have a dir, so get fh for /.SFSACL
void 
client::aclresolve_dir (svccb *sbp, filesrv::reqstate rqs,
			 ptr<acltargetlist> targets)
{ 
  acltarget *entry = targets->next_entry ();
  assert (entry);
  assert (entry->get_objecttype () == dir);
  
  diropargs3 args;
  args.dir = *entry->get_objectfhp ();
  args.name = SFSDIRACL;

  lookup3res *res = New lookup3res;
  
  rqs.c->call (NFSPROC3_LOOKUP, &args ,res, 
	       wrap (mkref (this), &client::aclresolve_dir_cb, sbp, rqs, res,
		     targets), 
	       auth_sfs);
}
Beispiel #29
0
//go read the acl
void 
client::aclresolve_file (svccb *sbp, filesrv::reqstate rqs,
			 ptr<acltargetlist> targets)
{
  acltarget *entry = targets->next_entry ();
  assert (entry);
  assert (entry->aclfh_known ());
  
  read3args args;
  args.file = *entry->get_aclfhp ();
  args.offset = ACLOFFSET;
  args.count = ACLSIZE;
  
  read3res *res = New read3res; 
  rqs.c->call (NFSPROC3_READ, &args, res, 
	       wrap (mkref (this), &client::aclresolve_file_cb, sbp,rqs, res,
		     targets),
	       auth_sfs);
}
Beispiel #30
0
void
sfsserver_auth::userauth::aresult (clnt_stat err)
{
  cbase = NULL;
  if (err) {
    warn << "sfscd: " << err << "\n";
    finish ();
  }
  else if (!ares.authenticate)
    finish ();
  else {
    sfs_loginarg arg;
    arg.seqno = seqno;
    arg.certificate = *ares.certificate;
    sp->sfsc->call (SFSPROC_LOGIN, &arg, &sres,
		    wrap (mkref (this),
			  &sfsserver_auth::userauth::sresult),
		    NULL, NULL, xdr_sfs_loginres_old);
  }
}