Beispiel #1
0
static IOOffer_clp FB_MgrStream_m (FB_clp self) {
    
    FB_st *st = (FB_st *)self->st;

#ifdef CONFIG_CALLPRIV
    CallPriv_AllocCode rc;
    CallPriv_clp cp;
    IOCallPriv_Info  info;
#endif
    IDCTransport_clp idc;
    IDCService_clp service;
    IOOffer_clp o;
    Type_Any any;

    extern void  process_mgr_pkt_stub();

    if (st->wssvr_shares_domain) {
	/* We are in the same domain - force WSSvr to use procedural
           interface */
	return NULL;
    }

#ifdef CONFIG_CALLPRIV    
    if(st->mgr_cp) {
	fprintf(stderr, "Already have one manager stream opened!!\n");
	return NULL;
    }

    cp = IDC_OPEN("sys>CallPrivOffer", CallPriv_clp);

#ifdef EB164
    rc = CallPriv$Allocate(cp, process_mgr_pkt_stub, st, &st->mgr_cp);
#else
    rc = CallPriv$Allocate(cp, process_mgr_pkt, st, &st->mgr_cp);
#endif
    
    if (rc != CallPriv_AllocCode_Ok) {
	fprintf(stderr, "Error initialising callpriv!\n");
	return NULL;
    }
    
    info = Heap$Malloc(Pvs(heap), sizeof(*info));
    
    info->slots = 64; 
    info->callpriv = st->mgr_cp;
    info->arg = 0;
    
    idc = NAME_FIND("modules>IOCallPrivTransport", IDCTransport_clp);
    
    TRC(fprintf(stderr, "Creating IOCallPriv update stream offer\n"));
    
    ANY_INIT(&any, IOCallPriv_Info, info);
    o = IDCTransport$Offer(idc, &any, NULL, Pvs(heap), 
			   Pvs(gkpr), NULL, &service);
    return o;
#else
    return NULL;
#endif
}
Beispiel #2
0
bool
OfferStream::step (Logs& l)
{
    // Modifying the order or logic of these
    // operations causes a protocol breaking change.

    auto viewJ = l.journal ("View");
    for(;;)
    {
        // BookTip::step deletes the current offer from the view before
        // advancing to the next (unless the ledger entry is missing).
        if (! tip_.step(l))
            return false;

        std::shared_ptr<SLE> entry = tip_.entry();

        // If we exceed the maximum number of allowed steps, we're done.
        if (!counter_.step ())
            return false;

        // Remove if missing
        if (! entry)
        {
            erase (view_);
            erase (cancelView_);
            continue;
        }

        // Remove if expired
        using d = NetClock::duration;
        using tp = NetClock::time_point;
        if (entry->isFieldPresent (sfExpiration) &&
            tp{d{(*entry)[sfExpiration]}} <= expire_)
        {
            JLOG(j_.trace) <<
                "Removing expired offer " << entry->getIndex();
            offerDelete (cancelView_,
                cancelView_.peek(keylet::offer(entry->key())), viewJ);
            continue;
        }

        offer_ = Offer (entry, tip_.quality());

        Amounts const amount (offer_.amount());

        // Remove if either amount is zero
        if (amount.empty())
        {
            JLOG(j_.warning) <<
                "Removing bad offer " << entry->getIndex();
            offerDelete (cancelView_,
                cancelView_.peek(keylet::offer(entry->key())), viewJ);
            offer_ = Offer{};
            continue;
        }

        // Calculate owner funds
        auto const owner_funds = accountFunds(view_,
            offer_.owner(), amount.out, fhZERO_IF_FROZEN, viewJ);

        // Check for unfunded offer
        if (owner_funds <= zero)
        {
            // If the owner's balance in the pristine view is the same,
            // we haven't modified the balance and therefore the
            // offer is "found unfunded" versus "became unfunded"
            auto const original_funds = accountFunds(cancelView_,
                offer_.owner(), amount.out, fhZERO_IF_FROZEN, viewJ);

            if (original_funds == owner_funds)
            {
                offerDelete (cancelView_, cancelView_.peek(
                    keylet::offer(entry->key())), viewJ);
                JLOG(j_.trace) <<
                    "Removing unfunded offer " << entry->getIndex();
            }
            else
            {
                JLOG(j_.trace) <<
                    "Removing became unfunded offer " << entry->getIndex();
            }
            offer_ = Offer{};
            continue;
        }

        break;
    }

    return true;
}
Beispiel #3
0
static IDCOffer_clp Mount_m(MountLocal_cl     *self, 
			    IDCOffer_clp       drive,
			    uint32_t           partition,
			    MountLocal_Options options, 
			    Context_clp        settings)
{
    IDCOffer_clp  res;
    ext2fs_st	 *st;
    Type_Any      any;
    Heap_clp      heap;
    struct inode *root            = NULL;
    uint32_t      blockcache_size = 1024*128; /* Size of blockcache in bytes */
    CSClientStubMod_cl *stubmod_clp; 


    TRC(printf("ext2fs: mount %d from %p\n", partition, drive));
    /* It's probably a good idea to have a separate heap for the filesystem.
       For now let's just use Pvs(heap), but eventually create a stretch
       of our own. */

    heap = Pvs(heap);

    if(!(st = Heap$Malloc(heap, sizeof(*st)))) {
	fprintf(stderr, "ext2fs: cannot allocate state.\n");
	RAISE_MountLocal$Failure();
    }

    /* Where is this declared? */
    bzero(st, sizeof(*st));

    /* Fill in the fields that we can initialise without accessing the
       filesystem */
    st->heap = heap;

    st->entrymod     = NAME_FIND("modules>EntryMod", EntryMod_clp);
    st->shmtransport = NAME_FIND("modules>ShmTransport", IDCTransport_clp);
    st->csidc        = NAME_FIND("modules>CSIDCTransport", CSIDCTransport_clp);


    st->client.entry = Pvs(entry);
    /* It's not clearn how many entries we are going to require yet
       We probably want separate ones for the USDCallback and the
       FSClient offers. We need to arrange that the entry threads die
       properly when the FS is unmounted. */


    /* Interpret mount flags */
    st->fs.readonly = SET_IN(options,MountLocal_Option_ReadOnly);
    st->fs.debug    = SET_IN(options,MountLocal_Option_Debug);


    /* Place the drive in the state. */
    st->disk.partition     = partition;
    st->disk.drive_offer   = drive;
    st->disk.drive_binding = IDCOffer$Bind(drive, Pvs(gkpr), &any);
    st->disk.usddrive      = NARROW(&any, USDDrive_clp);

 
    TRC(printf("ext2fs: state at [%p, %p]\n",st, (void *)st + sizeof(*st)));
    DBO(printf("ext2fs: debugging output is switched on\n"));

    /* Connect to the disk */
    init_usd(st);

    /* We need a stretch shared between us and the USD to allow us to read
       and write metadata. We'll use this stretch as a cache of blocks read
       from the disk. Because we won't know the blocksize until we have
       managed to read the superblock, we'd better make this buffer a
       multiple of 8k long (8k is currently the maximum blocksize). */

    st->cache.str = Gatekeeper$GetStretch(Pvs(gkpr), IDCOffer$PDID(drive), 
					  blockcache_size, 
					  SET_ELEM(Stretch_Right_Read) |
					  SET_ELEM(Stretch_Right_Write), 
					  PAGE_WIDTH, PAGE_WIDTH);
    st->cache.buf = STR_RANGE(st->cache.str, &st->cache.size);

    TRC(printf("ext2fs: buf is %d bytes at %p\n", st->cache.size,
	       st->cache.buf));
    if (st->cache.size < blockcache_size) {
	printf("ext2fs: warning: couldn't allocate a large blockcache\n");
    }

    /* Now we can get at the disk. Read the superblock, and calculate
       constants from it. */
    if (!read_superblock(st)) {
	printf("ext2fs: couldn't read superblock\n");
	shutdown_usd(st);
	RAISE_MountLocal$BadFS(MountLocal_Problem_BadSuperblock);
    }

    /* XXX should sanity check filesystem size with partition size */
    TRC(printf("ext2fs: filesystem size %d blocks (%d phys)\n"
	   "	    partition size %d blocks (%d phys)\n",
	   st->superblock->s_blocks_count,
	   PHYS_BLKS(st, st->superblock->s_blocks_count),
	   LOGICAL_BLKS(st, st->disk.partition_size),
	   st->disk.partition_size));
    if (st->disk.partition_size < 
	PHYS_BLKS(st, st->superblock->s_blocks_count)) {
	printf("WARNING - filesystem is larger than partition **********\n");
	/* XXX should probably give up now */
    }

    /* Now that we know the logical block size we can initialise the block
       cache */
    init_block_cache(st);

    /* From this point on, all access to the filesystem should be done
       through the block cache. DON'T call logical_read, call bread
       instead. Remember to free blocks once you're finished with them. */

    init_groups(st);

    if(!init_inodes(st)) {
	fprintf(stderr, "ext2fs: failed to initialise inode cache.\n");
	shutdown_usd(st);
	RAISE_MountLocal$Failure();
    }

    /* Checking this probably isn't a bad idea, but let's wait until later */

    /* Ok, now we are capable of reading the root inode (I hope!) */
    TRC(printf("ext2fs: checking root inode.\n"));
    root = get_inode(st, EXT2_ROOT_INO);
    if(!root) {
	fprintf(stderr, "ext2fs: failed to read root inode.\n");
	shutdown_usd(st);
	RAISE_MountLocal$BadFS(MountLocal_Problem_BadRoot);
    }
    
    if(!S_ISDIR(root->i_mode)) {
	fprintf(stderr, "ext2fs: urk!\n"
		"	 inode %d does not refer to a directory\n", 
		EXT2_ROOT_INO);
	shutdown_usd(st);
	RAISE_MountLocal$BadFS(MountLocal_Problem_BadRoot);
    }

    release_inode(st, root);

    /* *thinks* should probably do something about deallocating state
       if we fail, too. */

    /* Initialise the list of clients */
    LINK_INIT(&st->client.clients);
    /* We create a server for the local domain; it lives in the head
       of the list of clients. The call to CSIDCTransport$Offer() will
       set up client-side stubs for this domain and put them in the
       object table. */
    create_client(st, &st->client.clients, NULL);

    /* Now we do all the export stuff */
    CL_INIT(st->client.callback, &client_callback_ms, st);
    ANY_INIT(&any, Ext2_clp, &st->client.clients.cl);
    stubmod_clp = Heap$Malloc(st->heap, sizeof(*stubmod_clp)); 
    CLP_INIT(stubmod_clp, &stubmod_ms, NULL);
    res = CSIDCTransport$Offer (
	st->csidc, &any, FSClient_clp__code, stubmod_clp,
	&st->client.callback, /* XXX produces a warning */
	st->heap, Pvs(gkpr), st->client.entry, &st->client.service);

    TRC(printf("ext2fs: offer at %p\n",res));

    return res;
}
Beispiel #4
0
static void init_usd(ext2fs_st *st)
{
    USD_PartitionInfo	 info;
    Type_Any		 any;
    IDCOffer_clp         partition;

    
    USDTRC(printf("ext2fs: Creating USDCallbacks\n"));
    {
	IDCTransport_clp    shmt;
	IDCOffer_clp        offer;
	IDCService_clp      service;
	L1_st              *l1_st;

	/* Get a heap writable by the USD domain */
	st->disk.heap = 
	    Gatekeeper$GetHeap(Pvs(gkpr), 
			       IDCOffer$PDID(st->disk.drive_offer), 0, 
			       SET_ELEM(Stretch_Right_Read) | 
			       SET_ELEM(Stretch_Right_Write),
			       True);

	/* The L1 callback executes there */
	l1_st = Heap$Malloc(st->disk.heap, sizeof(L1_st));
	l1_st->ext2fs_st = st;	/* our state is read-only in USD
				   domain */
	st->disk.l1_callback = &(l1_st->l1_callback);
	CLP_INIT(st->disk.l1_callback, &L1_ms, l1_st);

	/* Create an offer for the L2 Callback */
	CL_INIT(st->disk.l2_callback, &L2_ms, st);
	ANY_INIT(&any,USDCallback_clp, &st->disk.l2_callback);
	shmt  = NAME_FIND ("modules>ShmTransport", IDCTransport_clp);
	offer = IDCTransport$Offer (shmt, &any, NULL,
				    Pvs(heap), Pvs(gkpr),
				    Pvs(entry), &service); 
	
	/* Put it in the L1 callback's state record */
	l1_st->l2_offer = offer;
    }

    USDTRC(printf("ext2fs: Getting USDCtl offer\n"));
    if(!USDDrive$GetPartition(st->disk.usddrive,
			      st->disk.partition,
			      st->disk.l1_callback,
			      &partition)) {
	return;
    }
    
	
    USDTRC(printf("ext2fs: Binding to USDCtl offer\n"));
    /* Bind to the USD. Do this explicitly rather than through the object
       table; we don't want anybody else getting hold of this one. */
    st->disk.binding = IDCOffer$Bind(partition, Pvs(gkpr), &any);
    st->disk.usdctl  = NARROW(&any, USDCtl_clp);

    /* Find out some information */
    USDTRC(printf("ext2fs: fetching partition info\n"));
    if(!USDDrive$GetPartitionInfo(st->disk.usddrive, 
				  st->disk.partition, 
				  &info)) {
	return;
    }

    st->disk.phys_block_size = info.blocksize;
    st->disk.partition_size  = info.size;
    DBO(printf("ext2fs: blocksize %d, partition size %d blocks,\n"
	       "	partition type %s\n",
	       st->disk.phys_block_size, 
	       st->disk.partition_size,
	       info.osname));
    FREE(info.osname);

    return; 
}
Beispiel #5
0
void NetworkQueue::Offer(std::auto_ptr<Data> value)
{
	// Indicate that we released this from an auto_ptr
	Offer(value.release(), true);
}
Beispiel #6
0
static IDCOffer_clp UnixLoginMod_New_m (
    UnixLoginMod_cl     *self,
    IDCOffer_clp    fs      /* IN */,
    string_t        passwd  /* IN */,
    string_t        group   /* IN */ )
{
    UnixLoginMod_st     *lst;
    Login_st        *st;
    FSClient_clp     fsclient;
    Type_Any         any, *dirany;
    FSTypes_RC       rc;
    FSDir_clp        dir;
    FileIO_clp       fileio;
    Rd_clp           rd;
    FSUtil_clp       fsutil;
    StringTblMod_clp strtbl;
    IDCTransport_clp shmt;
    IDCOffer_clp     offer;
    IDCService_clp   service;
    char buff[124];

    TRC(printf("UnixLoginMod_New_m(%p, %s, %s)\n",fs,passwd,group));

    fsutil=NAME_FIND("modules>FSUtil", FSUtil_clp);
    strtbl=NAME_FIND("modules>StringTblMod", StringTblMod_clp);
    shmt=NAME_FIND("modules>ShmTransport", IDCTransport_clp);

    lst=Heap$Malloc(Pvs(heap), sizeof(*lst));
    lst->heap=Pvs(heap);

    /* Bind to security service */
    TRC(printf(" + binding to security service\n"));
    lst->sec=IDC_OPEN("sys>SecurityOffer", Security_clp);

    /* Bind to FS */
    TRC(printf(" + binding to filesystem\n"));
    fsclient=IDC_BIND(fs, FSClient_clp);
    
    rc=FSClient$GetDir(fsclient, "", True, &dirany);
    if (rc!=FSTypes_RC_OK) {
	printf("UnixLoginMod: couldn't get directory\n");
	FREE(lst);
	return NULL;
    }

    dir=NARROW(dirany, FSDir_clp);
    FREE(dirany);

    /* Create tables */
    TRC(printf(" + creating tables\n"));
    lst->users=StringTblMod$New(strtbl, lst->heap);
    lst->groups=StringTblMod$New(strtbl, lst->heap);
    lst->certificate_tbl=StringTblMod$New(strtbl, lst->heap);
    lst->certificate_id = 1;

    /* Read in passwd file */
    TRC(printf(" + reading password file\n"));
    rc=FSDir$Lookup(dir, passwd, True);
    if (rc!=FSTypes_RC_OK) {
	printf("UnixLoginMod: couldn't lookup passwd file\n");
	FREE(lst);
	return NULL;
    }

    rc=FSDir$Open(dir, 0, FSTypes_Mode_Read, 0, &fileio);
    if (rc!=FSTypes_RC_OK) {
	printf("UnixLoginMod: couldn't open passwd file\n");
	FREE(lst);
	return NULL;
    }

    rd=FSUtil$GetRd(fsutil, fileio, lst->heap, True);
    
    while (!Rd$EOF(rd))
    {
	uint32_t l;
	l=Rd$GetLine(rd, buff, 120);
	buff[l]=0;
	/* TRC(printf("->%s\n",buff)); */
	add_passwd_line(lst, buff);
    }

    Rd$Close(rd);

    /* Read in group file */
    TRC(printf(" + reading group file\n"));
    rc=FSDir$Lookup(dir, group, True);
    if (rc!=FSTypes_RC_OK) {
	printf("UnixLoginMod: couldn't lookup group file\n");
	FREE(lst);
	return NULL;
    }

    rc=FSDir$Open(dir, 0, FSTypes_Mode_Read, 0, &fileio);
    if (rc!=FSTypes_RC_OK) {
	printf("UnixLoginMod: couldn't open group file\n");
	FREE(lst);
	return NULL;
    }

    rd=FSUtil$GetRd(fsutil, fileio, lst->heap, True);

    while (!Rd$EOF(rd))
    {
	uint32_t l;
	l=Rd$GetLine(rd, buff, 120);
	buff[l]=0;
	/* TRC(printf("=>%s\n",buff)); */
	add_group_line(lst, buff);
    }

    Rd$Close(rd);

    /* We don't need the filesystem any more */
    FSDir$Close(dir);

    LINK_INITIALISE(&lst->certificate_list);

    MU_INIT(&lst->mu);

    /* Closure for local access to the server */

    st=Heap$Malloc(lst->heap, sizeof(*st));
    CL_INIT(st->cl, &login_ms, st);
    st->id=VP$DomainID(Pvs(vp));
    st->lst=lst;

    /* Export */
    TRC(printf(" + exporting Login service\n"));
    ANY_INIT(&any, Login_clp, &st->cl);
    CL_INIT(lst->callback, &callback_ms, lst);
    offer=IDCTransport$Offer(shmt, &any, &lst->callback, lst->heap,
			     Pvs(gkpr), Pvs(entry), &service);

    return offer;
}
Beispiel #7
0
bool
OfferStream::step ()
{
    // Modifying the order or logic of these
    // operations causes a protocol breaking change.

    for(;;)
    {
        // BookTip::step deletes the current offer from the view before
        // advancing to the next (unless the ledger entry is missing).
        if (! m_tip.step())
            return false;

        SLE::pointer const& entry (m_tip.entry());

        // Remove if missing
        if (! entry)
        {
            erase (view());
            erase (view_cancel());
            continue;
        }

        // Remove if expired
        if (entry->isFieldPresent (sfExpiration) &&
                entry->getFieldU32 (sfExpiration) <= m_when)
        {
            view_cancel().offerDelete (entry->getIndex());
            if (m_journal.trace) m_journal.trace <<
                                                     "Removing expired offer " << entry->getIndex();
            continue;
        }

        m_offer = Offer (entry, m_tip.quality());

        Amounts const amount (m_offer.amount());

        // Remove if either amount is zero
        if (amount.empty())
        {
            view_cancel().offerDelete (entry->getIndex());
            if (m_journal.warning) m_journal.warning <<
                        "Removing bad offer " << entry->getIndex();
            m_offer = Offer{};
            continue;
        }

        // Calculate owner funds
        // NIKB NOTE The calling code also checks the funds, how expensive is
        //           looking up the funds twice?
        Amount const owner_funds (view().accountFunds (
                                      m_offer.account(), m_offer.amount().out, fhZERO_IF_FROZEN));

        // Check for unfunded offer
        if (owner_funds <= zero)
        {
            // If the owner's balance in the pristine view is the same,
            // we haven't modified the balance and therefore the
            // offer is "found unfunded" versus "became unfunded"
            if (view_cancel().accountFunds (m_offer.account(),
                                            m_offer.amount().out, fhZERO_IF_FROZEN) == owner_funds)
            {
                view_cancel().offerDelete (entry->getIndex());
                if (m_journal.trace) m_journal.trace <<
                                                         "Removing unfunded offer " << entry->getIndex();
            }
            else
            {
                if (m_journal.trace) m_journal.trace <<
                                                         "Removing became unfunded offer " << entry->getIndex();
            }
            m_offer = Offer{};
            continue;
        }

        break;
    }

    return true;
}
Beispiel #8
0
static FB_StreamID FB_UpdateStream_m (
        FB_cl          *self,
        FB_WindowID     wid     /* IN */,
        FB_Protocol     p       /* IN */,
        FB_QoS          q       /* IN */,
        bool_t          clip    /* IN */
       /* RETURNS */,
        IOOffer_clp   *io,
	FBBlit_clp     *blit)
{
    FB_st *st = (FB_st *)self->st;
    FB_Window *w = &st->window[wid];
    FB_StreamID NOCLOBBER        sid = 0;
    FB_Stream *NOCLOBBER s;
    
    TRC(fprintf(stderr,"FB_UpdateStream_m (%p, %lx, %d, %d, %d)\n",
		self, wid, p ,q, clip));

    TRC(fprintf(stderr,"Finding an unused stream\n"));
    /* Find an unused stream */
    ENTER();
    while (sid < FB_MAX_STREAMS && !st->stream[sid].free) sid++;
    if (sid < FB_MAX_STREAMS) {
	s = &st->stream[sid];
	s->free = False;
    } 
    LEAVE();
    
    if (sid == FB_MAX_STREAMS) RAISE_FB$Failure();
    
    TRC(fprintf(stderr,"Setting up stream %d\n", sid));
    /* Set up an update stream offer */
    {
	IOTransport_clp	iot;
	IDCService_clp      service;
	IDCService_clp      sv;
	IDCOffer_clp        o;
	
	/* XXX NAS: Want to work out stream from IO_clp handed beck from a 
	 * rendezvous - slap it in handle until someone gives me a better
	 * idea.
	 */
	TRC(fprintf(stderr,"Digging up IO Transport\n"));  
	iot = NAME_FIND ("modules>IOTransport", IOTransport_clp);
	TRC(fprintf(stderr,"Making IO transport OFfer\n"));
	
	o = IOTransport$Offer (iot, Pvs(heap), 128, IO_Mode_Tx, IO_Kind_Master,
			       NULL, Pvs(gkpr), NULL, st->fbentry, (word_t)s, 
			       &service);

	TRC(fprintf(stderr, "Made IOTransport offer\n"));

	/* Can potentially use IDCService to revoke the offer */
	s->service = service;
	s->offer   = o;
	
	s->w       = w;
	s->proto   = p;

	s->blit_m = st->blit_fns[p];

    } 

#ifdef CONFIG_CALLPRIV

    TRC(fprintf(stderr, "Making Callpriv blit offer\n"));
    TRY {
	*blit = FBBlitMod$New(NAME_FIND("modules>FBBlitMod", FBBlitMod_clp),
			      sid, st->blit_cps[p]);
    } CATCH_Context$NotFound(n) {
	fprintf(stderr, "Unable to locate '%s'\n", n);
	RAISE_FB$Failure();
    } ENDTRY;
#else

    *blit = NULL;

#endif

    *io = s->offer;
    TRC(fprintf(stderr,"FB_UpdateStream_m: Done, Offer:%x\n",*io ));
    
    return sid;
}