/* static */ SysStatus RegionReplicated::_CreateFixedLenExtDyn(uval& regionVaddr, uval regionSize, uval alignmentreq, ObjectHandle frOH, uval fileOffset, uval accessreq, XHandle target, ObjectHandle tsOH, RegionType::Type regionType, __CALLER_PID callerPID) { RegionRef ref; ProcessRef pref=0; SysStatus rc; FCMRef fcmRef; TypeID type; ObjRef objRef; FRRef frRef; rc = RegionDefault::PrefFromTarget(target, callerPID, pref); _IF_FAILURE_RET(rc); rc = XHandleTrans::XHToInternal(frOH.xhandle(), callerPID, MetaObj::attach, objRef, type); tassertWrn(_SUCCESS(rc), "RegionReplicated failed XHToInternal\n"); _IF_FAILURE_RET(rc); // verify that type is of FRComp - we'd really like just FR // FIXMEXX talk to Orran, the brilliant, charming, .. if (!MetaFR::isBaseOf(type)) { tassertWrn(0, "object handle <%lx,%lx> not of correct type\n", frOH.commID(), frOH.xhandle()); return _SERROR(1542, 0, EINVAL); } //FIXME check xobj to make sure it matches our processID frRef = (FRRef)objRef; rc = RegionReplicated::CreateFixedLen( ref, pref, regionVaddr, regionSize, alignmentreq, frRef, fileOffset, (AccessMode::mode)accessreq); // FIXME: Kludge for enabling dyn-switch #if 0 CObjRoot *partitionedFCMRoot = 0; rc = FCMPartitionedTrivial::Create(partitionedFCMRoot, fcmRef, regionSize, /* number of cache lines per rep */ 256, /* associativity of each line */ 4); tassert(_SUCCESS(rc), err_printf("Replicated Trivial fcm create\n")); PMRef pmRef; rc = DREF(pref)->getPM(pmRef); tassert(_SUCCESS(rc), ;);
int main() { NativeProcess(); SysStatus rc; ObjectHandle oh; UsrTstRef ref = UsrTst::Create(); rc = DREF(ref)->giveAccessByServer(oh, _KERNEL_PID); tassert(_SUCCESS(rc), err_printf("woops\n")); printf("testDisabledIPC: calling kernel with oh %lx %lx\n", oh.commID(), oh.xhandle()); Scheduler::Disable(); ALLOW_PRIMITIVE_PPC(); DREFGOBJ(TheProcessRef)->testUserIPC(oh); UN_ALLOW_PRIMITIVE_PPC(); Scheduler::Enable(); printf("testDisabledIPC: done calling kernel\n"); for (uval i = 0; i < 20; i++) { printf("testDisabledIPC: sleeping (%ld)\n", i); Scheduler::DelayMicrosecs(5000); } printf("testDisabledIPC: terminating\n"); return 0; }
/* static */ SysStatus LinuxPTYServer::Create(ObjectHandle &oh, TypeID &type, dev_t num, ProcessID pid, uval oflag) { SysStatus rc; int ret; LinuxPTYServer *pty = new LinuxPTYServer(); LinuxPTYServerRef ref; pty->devNum = num; pty->availMask = FileLinux::INVALID; CObjRootSingleRep::Create(pty); ref = (LinuxPTYServerRef)pty->getRef(); pty->readCB.obj = ref; pty->writeCB.obj = ref; rc = DREF(ref)->giveAccessByServer(oh, pid); if (_FAILURE(rc)) { DREF(ref)->destroy(); return rc; } ProcessLinux::LinuxInfo info; rc = DREFGOBJ(TheProcessLinuxRef)->getInfoNativePid(pid, info); tassertMsg(_SUCCESS(rc), "Couldn't get info about k42 process 0x%lx\n", pid); PTYTaskInfo ptyTI(info.pid, info.pgrp, info.session, info.tty, info.pid == info.session); LinuxEnv sc(SysCall, ptyTI.t); ret = ttydev_open(&pty->oli, num, &pty->readQ, &pty->writeQ, oflag|O_NONBLOCK); if (ret<0) { rc = _SERROR(2365, 0, -ret); // releaseAccess will trigger destroy DREF(ref)->releaseAccess(oh.xhandle()); } else { pty->devNum = ret; //Put ourselves on wait queue with TTYEvents object that will // generate callbacks instead of waking threads if (pty->readQ && list_empty(&pty->readCB.task_list)) { add_wait_queue(pty->readQ, &pty->readCB); } if (pty->writeQ && list_empty(&pty->writeCB.task_list)) { add_wait_queue(pty->writeQ, &pty->writeCB); } type = (TypeID)new_encode_dev(pty->devNum); } return rc; }
/* static */ SysStatus FileLinuxVirtFile::LazyReOpen(FileLinuxRef &flRef, ObjectHandle oh, char *buf, uval bufLen) { SysStatus rc; LazyReOpenData *d = (LazyReOpenData *)buf; tassertMsg((bufLen == sizeof(LazyReOpenData)), "got back bad len\n"); err_printf("FLVF: lazy re open: %lx\n",oh.xhandle()); rc = Create(flRef, oh, d->openFlags); return rc; }
/* virtual */ SysStatus MemTrans::giveAccessSetClientData(ObjectHandle &oh, ProcessID toProcID, AccessRights match, AccessRights nomatch, TypeID type) { SysStatus rc; ClientData *clientData = new ClientData(toProcID); rc = giveAccessInternal(oh, toProcID, match, nomatch, type, (uval)clientData); if (_FAILURE(rc)) { delete clientData; } // Remember the process binding BaseProcessRef pref; rc = DREFGOBJ(TheProcessSetRef)->getRefFromPID(toProcID,pref); _IF_FAILURE_RET_VERBOSE(rc); XHandle remote = oh.xhandle(); //Add ref count for xhandle incRefCount(); rc = DREF(pref)->addSMT(getRef(), remote, key); _IF_FAILURE_RET(rc); clientData->givenOH = oh; cdHash.add(toProcID, clientData); dprintf("%s: add xh: %lx -> %ld\n",__func__,oh.xhandle(),toProcID); return rc; }
/* virtual */ void StreamServerConsole::startLoginShell(ObjectHandle &oh, ProcessID initPID) { SysStatus rc; lock(); rc = giveAccessByClient(oh, initPID); tassertMsg(_SUCCESS(rc), "woops %lx\n", rc); // Mark login handle login = oh.xhandle(); // now start the polling read Scheduler::ScheduleFunction(StreamServerConsole::ReadFromConsole, (uval)this); unlock(); }
/* virtual */ SysStatus MemTrans::init(ProcessID partner, XHandle &remoteX, uval size, MTEvents *handler) { debug = 0; SysStatus rc = 0; CObjRootSingleRep::Create(this); uval addr = 0; ObjectHandle myFRInt; ObjectHandle localOH; ObjectHandle remoteOH; localSize = size; //Ref count is 1 --- for whoever created this object refCount = 1; allocLock.init(); cbs = handler; // Lock out allocations until we're done initialization AutoLock<LockType> al(&allocLock); // Give other process access to this MT rc = giveAccessByServer(localOH, partner); _IF_FAILURE_RET(rc); remoteX = localOH.xhandle(); usedPages.append(new PageUse(localSize/PAGE_SIZE, 0)); // Create FR for local-side memory area (that will be exported) rc = StubFRComputation::_Create(myFRInt); _IF_FAILURE_RET_VERBOSE(rc); localFR.setOH(myFRInt); rc = StubRegionDefault::_CreateFixedLenExt( localBase, localSize, 0, myFRInt, 0, AccessMode::writeUserWriteSup, 0, RegionType::K42Region); _IF_FAILURE_RET_VERBOSE(rc); // Create an OH to a global object in the other process and // look for a matching MemTrans there // But, if this is the kernel, we never attempt this --- // Can't trust the other process to not block us on this // So we always wait for the other process to call _swapHandle if (DREFGOBJ(TheProcessRef)->getPID() == _KERNEL_PID) { return 0; } ObjectHandle SMTDB; SMTDB.initWithPID(partner,XHANDLE_MAKE_NOSEQNO(CObjGlobals::ProcessIndex)); StubProcessClient stubPC(StubObj::UNINITIALIZED); stubPC.setOH(SMTDB); rc = stubPC._getMemTrans(remoteOH, key); if (_SUCCESS(rc)) { StubMemTrans remote(StubObj::UNINITIALIZED); remote.setOH(remoteOH); uval remoteSize; ObjectHandle frOH; // Give access to this area to the other process // FIXME: give access for read only ObjectHandle myFRExt; rc = localFR._giveAccess(myFRExt, partner); _IF_FAILURE_RET_VERBOSE(rc); // Give remote process OH's to our FR and MT rc = remote._swapHandle(localOH, myFRExt, localSize, remoteSize, frOH); _IF_FAILURE_RET_VERBOSE(rc); rc = StubRegionDefault::_CreateFixedLenExt( addr, remoteSize, 0, frOH, 0, AccessMode::writeUserWriteSup, 0, RegionType::K42Region); _IF_FAILURE_RET_VERBOSE(rc); ClientData *cd = clnt(remoteX); cd->init(frOH, remoteOH, addr, remoteSize); remote._completeInit(); } return 0; }