| 
  • If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

  • You already know Dokkio is an AI-powered assistant to organize & manage your digital files & messages. Very soon, Dokkio will support Outlook as well as One Drive. Check it out today!

View
 

Dominions

Page history last edited by Michael van der Gulik 9 years, 4 months ago

Dominions

 

Dominions are used for resource control, where a resource could be, for example:

 

Each Dominion is allocated certain levels of resources depending on the user's preferences. Resources include:

  • CPU usage (i.e. a certain number of CPU cycles, threads or CPU priority are donated to a dominion).
  • Memory usage (i.e. a certain number of MB are donated to a dominion).
  • Network bandwidth.
  • Disk usage (i.e. a certain number of MB are donated to a dominion)
  • Device usage.
  • Access to capabilities.

 

Each dominion has resources donated to it. Code runs within a dominion and consumes those resources. The dominion is billed for the use of those resources, and when the dominion runs out, then the code will (probably) be suspended until more resources are available.

 

Dominions were originally invented for SecureSqueak, but are generally applicable to any computing environment. In an object-oriented VM, for example, every object is in a dominion. A dominion is billed for the storage of that object. When a method is invoked on that object, the dominion is billed for those CPU cycles. If a method is invoked on another object, that other object might be part of another dominion where resources will be billed.

 

For example, say that a SiteBrowser is an application that visits Sites which are implemented by code loaded from across a network. Each Site has an associated Dominion. When a Site object has been instantiated, new resources are granted to that Site's dominion (for example, CPU priority capped at 35, no more than 10MB disk, no more than 20MB/s over the network, access only to sound and a Canvas). When the SiteBrowser leaves that Site and goes to another, those resources will be denied to the previously visited Site's dominion. In this way, it is impossible for a particular Site to exceed its resource usage and cause a denial of service to other objects in an image.

 

Dominions can be managed by the user. For example, when a user deletes a "document" (which is a bunch of related objects in a special dominion for that document), all resources are un-donated to that dominion. If gracefully deleted, objects would be garbage collected until the dominion is consuming no resources. If ungracefully deleted (a.k.a kill -9), CPU is denied to those objects and the objects are forceably nulled.

 

The information about which Dominions can access how much of each resource is stored externally to the Dominions, perhaps by a DominionManager?

 

In a distributed system involving multiple running images communicating over a network, a "Dominion" could span multiple machines. In this case, distributed services could also use the dominion mechanism to find resources such as an idle CPU or disk space. Each physical machine has it's own local dominion which owns all resources on that machine. Each dominion can donate resources to other dominions. So, code can be executed in the local dominion, which gives code inside that dominion full access to all CPU, memory and disk space. Typically, though, code will run in it's own dominion, and the local dominion will donate resources to the new dominion. If a networked / clustered environment is used, each node's local dominion can donate all resources to a single dominion for the whole network, and that single dominion can then donate resources to specific-use dominions hosted on that cluster.

 

Dominions can be used for stating the requirements of code: this code requires at least 200MIPS CPU, 20MB object space and 10MB/s network or it won't run well. This will allow the computer to state that it cannot meet the requirements of all the dominions it is hosting.

 

Dominions form a mechanism of controlling and accounting resources on remote machines. This allows hosting providers (ISPs etc) to account and charge for services provided.

 

Implementation

 

When a new dominion is created, an existing dominion is required so that resources can be donated.

 

Some API for managing dominions is required, to handle:

  • Dominion lifecycle: creating, deallocating.
  • Resource requests.
  • Resource donations.
  • Notifications for dominions that run out of resources.
  • Searching for free resources within a distributed dominion (e.g. finding a free CPU core, memory or storage on a remote node).

 

For an implementation using, e.g. LLVM:

  • Each process runs in a dominion.
  • When a process is scheduled, CPU accounting and billing is done.
  • When memory is allocated or freed, the dominion is billed and refunded.
  • Ditto for disk usage, network usage.
  • Forked processes can be run in a new dominion.

 

For an implementation in Faish:

  • Each module belongs to a dominion.
  • Searches are run in the dominion for the module they are initialized in.
  • Searches that run across imports still bill the dominion they were initialized in.

 

For an implementation in an object-oriented VM, a Dominion is an Object.

 

Every object in an image belongs to one Dominion. The reason for this rather than making a Package belong to a dominion (in the same manner that Java applies security permissions to jar files) is because multiple groups of objects might have different security requirements but share the same code. For example, an image might have several objects of class Document, but each Document instance would be in its own Dominion so that one particular Document doesn't consume all the resources for every Document in the image.

 

Making every object belong to a Dominion can be implemented in multiple ways:

 

  • In the current prototype, a complicated manner of copying classes and metaclasses is used, and the metaclasses are assigned to a particular Dominion. When an object is assigned to a dominion, a shallow copy of that object's class is made using a metaclass assigned to that Dominion. The object is then changed to be of this new class.
  • It is possible to add an instance variable called "dominion" to every single object in an image.
  • It would be possible to modify the VM to group objects of a single dominion together in memory and provide VM primitives to return the dominion of a particular object. This would require extensive changes.
  • It would be possible using a global dictionary and clever use of the tracing technology that ImageSegments uses to store knowledge about which objects belong to which dominions.
  • It would be possible to make programmers manually implement dominions. In the same way that Java has a doPrivileged() method, a method could be added to BlockContext that will mark the current thread as now "entering" a particular dominion. The programmer would have to use this method at every entry point on a particular API and would need to store that dominion.

 

For shared objects (such as services), these would need to run in a separate dominion from the dominion that spawned them. E.g. if a package is downloaded, it should be in a separate "service" dominion. Otherwise, the dominion that spawned it will be billed for any further resource use of this shared resource.

 

Problematic objects

(from "Smalltalk specialObjectsArray")

The VM makes assumptions about the structure of these objects.

  • Classes, CompiledMethods, Dictionaries, Metaclass
  • nil / true / false
  • Array, BitMap, ByteString, Symbol, ByteArray, WeakArray
  • SmallInteger
  • LargePositiveInteger, LargeNegativeInteger
  • Float
  • MethodContext, BlockContext, Process, PseudoContext (?), TranslatedMethod (?)
  • Point, Rectangle
  • DisplayScreen
  • Message 
  • Semaphore
  • Character
  • Association
  • EventSensor
  • ExternalAddress, ExternalStructure, ExternalData, ExternalFunction, ExternalLibrary (? what are these?)
  • objects from plug-ins (e.g. sound) 

I need to grep the VM source code for direct instvar accesses.

 

When the object has negligable storage requirements and cannot be subclassed, then it can refer to its invoker for the current dominion.

 

Variable subclasses of things other than objects (i.e. bytes, words, floats) cannot have extra instance variables. This is a big problem as these can be big. Perhaps VM modifications are needed??

 

Finding the active Dominion

 

The active dominion will need to be accessed when:

  • The scheduler is invoked and adds accounting information to the dominion that just ran.
  • A new object is created or released (i.e. memory is allocated and released). New entries on the call stack are also objects.
  • A resource is accessed, such as disk or network. 

 

The resources of most interest are CPU and memory.

 

The dominion of an instance method is the dominion of the object that method is invoked on. The memory and CPU used would be charged to that object's dominion. Memory for the MethodContext is charged to the object that method is invoked on, unless that object has no dominion, in which case the call stack should be inpected.

 

When a block is used, memory for the BlockContext is charged to the object that makes it; CPU is charged to the object that invokes it.

 

The dominion of a class method would be the dominion of that class object. The memory would be charged to that class's dominion. The CPU would be charged to...??? maybe CPU would be charged to the invoker?

 

When a Process object is made, memory is charged to the object that makes it (perhaps this follows the rules of making a new object); CPU is charged to ??? the invoker of whatever method is called?

 

When a SmallInteger is instantiated, memory is not charged (none is used). When methods are invoked, they'll need to use the dominion of the invoker to charge memory (MethodContext) to. CPU is charged to the invoker.

 

When a new object is made, its dominion (if it can have one) is the dominion of whatever object made it, except when that new object can't have a dominion (SmallIntegers) or when a new dominion will be made.

 

Memory usage can be controlled by modifying ProtoObject>>basicNew(...) to first check if the given dominion is still permitted to create new objects. The garbage collector would need to be modified to decrement the memory usage of that dominion when objects are disposed.

 

There doesn't need to be a limit on the size of a call stack or number of forked processes. Provided that the scheduler bases the amount of CPU time a dominion gets fairly (and not in proportion to the number of threads that dominion has forked), a dominion is only constrained by its memory limits when forking new processes or invoking recursive methods.

 

The implementation of the Squeak scheduler could be modified to give fair CPU access across all dominions. A limit on the highest priority available to a dominion can be enforced.

 

A limit on the number of forked processes could be put into place to simulate the use of a set of worker threads. When that limit has been reached, the next "[...] fork" will block until another process in that dominion has terminated. This could unfortunately be a source of bugs; if code requires a certain number of processes to work but it cannot create that many processes, that program may fail. A better solution would be to implement the scheduler to favour executing child threads to completion rather than creating new processes.

 

When a dominion is revoked, the dominion could have some event or callback mechanism to have that dominion's object tidy up after themselves. After that, the dominion can be forcefully removed and references to any object in that dominion nullified.

 

When a dominion reaches one or another limit, an exception will need to be thrown from... somewhere? If the dominion can't handle the situation (by decreasing resource usage) then the user will need to be notified.

 

Resource allocation

 

Maximum values are specified to control resource usage.

Minimum values are used to decide whether the hosting machine has enough spare capacity to host this dominion. A particular machine cannot allocate more than 100% of its resources.

 

CPU

 

CPU usage is either batch or real-time. Batch tasks don't mind being denied CPU for a few seconds or minutes. Real-time tasks do.

 

CPU can be allocated using:

  • Total number of instructions allowed before this dominion is halted.
  • Minimum and maximum total number of batch or real-time instructions per second allowed. (Does it make sence to specify a maximum number of batch instructions per second?)
  • Maximum/minimum batch/real-time CPU priority of this dominion.

 

A service that is being hosted on a particular CPU would have real-time and batch CPU requirements. The real-time component provides a minimum level of service even if the machine is under high load; the batch component will allow idle resources on that machine to be utilised.

 

Currently in Squeak, CPU priority is an all-or-nothing affair. The highest priority task gets all CPU.

 

How would this be implemented? Is putting limits on CPU usage even an issue? Provided that the system remains responsive, it does not matter how many threads are spawned, and the scheduler would distribute CPU per dominion rather than per process so that a fork bomb would be contained within a dominion and constrained by memory usage.

 

CPU Scheduling

 

Processes could be:

  • Real-time / interactive: They get switched to immediately if they are needed, but if they run for too long they loose this privilege. This is for UI tasks, network I/O, etc.
  • Ordinary: these are round-robined by dominion and are not resource starved.
  • Batch: These run if the system goes idle. These may not run if the system is running on batteries. These will not charge the dominion. 

 

The Scheduler would

when invoked by a periodic timer:

  • If control is coming from a real-time thread, punish it and possibly transfer control back to it if it hasn't been punished too much so far. Real-time threads should not be interrupted by timers because they should do their work quickly and then wait on a semaphore.
  • If a real-time thread is waiting, transfer to that.
  • Otherwise round-robin through ordinary processes.
  • If there are no ordinary processes, round-robin through batch processes.

when entered by a waited semaphore:

  • Do the same as for a timer. 
  • Try to guess which process would signal that semaphore and go there, unless that process has run too much lately. 

when entered by a signalled semaphore (optional):

  • Transfer control to a process that is waiting on that semaphore, or if the VM is truly multitasking, then use another OS process to do this. This improves reactiveness. 

 

Some way of handling a stalled thread should exist:

[ doSomething ] onTimeout: 500ms do: [ something ].

 

Network

 

Network resource management is complicated. More thought needed here.

 

Network usage might have different types (QOS settings), interfaces or routes, such as different dominion settings for low-latency connections or high-latency high-bandwidth (e.g. satellite) connections. LAN packets would typically be unrestricted, while remote access could be throttled.

 

Users might want to:

  • Specify that they have a bandwidth limit per time period.
  • Specify that they want to minimize unnecessary network usage.
  • Allow use of only a certain percentage of network bandwidth.
  • Give some dominions priority over others (using QOS settings?).
  • Specify that particular times of day have different limits.
  • Some dominions might be prevented from using particular routes, e.g. business-specific objects might be disallowed from traversing a firewall. 

 

Users will want to get summaries of network usage per dominion (as they do with other resources).

 

Memory

 

Memory can be allocated by specifying the maximum size and minimum size requirements needed to run.

 

Types of memory include normal and cache. "Cache" memory is memory that can be discarded if resources are low; a memory manager of some sort would look at the "cache" memory usage values for each dominion and make decisions as to which dominions are asked to discard cache.

 

A service would usually specify a minimum memory requirement; if the local machine cannot supply that much memory then that service will not be able to be run.

 

The maximum requirements don't always need to be specified; these exist primarily to avoid run-away resource usage as a result of memory leaks, and for accounting purposes so that memory hogs can be terminated to free up memory.

 

Disk 

Disk can be allocated by specifying the maximum size and minimum size requirements needed to run. This is similar to memory.

 

Resource balancing

 

All these resources need to be shared evenly between all hosted dominions based on priorities.

 

Usage notifications

 

When a resource is nearing saturation (e.g. at 80%?), that dominion will be sent a notification that gives it an opportunity to reduce resource usage. This also applies when resource allocations are modified - say for example that memory is reduced from 20MB to 10MB for a particular dominion; the resource is first notified; the notification thread is given some time to complete and then the resource allowance for that dominion is reduced.

 

Resource theft

 

Preventing resource theft

 

If Object>>dominion returns that object's dominion, then any class could access that dominion and make objects in that dominion. This allows for resource theft. This means that Object>>dominion cannot return a dominion that allows for resource usage in the returned dominion.

 

So how do you allow only the DominionManager to work out which object is in which dominion?

 

More generally, how do you make sure that a method can only return a confidential result to one object?

  • Maybe the dominion is only passed out in invocations on other objects?

private methods:

 

thisContext sender receiver = self ifFalse: [^ SecurityException signal]

or

thisContext sender receiver class = DominionManager ifFalse: [^ SecurityException signal].

or

(Sender is: self) ifTrue: [...]

(where Sender is a global variable that doesn't let you get the actual reference.)

 

Means of resource theft

 

Access to an object's dominion by another object not in that dominion allows resource theft.

 

APIs available to objects outside the current dominion may allow for a memory leak. This can happen by, for example, objects in one dominion holding on to objects in another dominion thus preventing them from being GCed.

 

A block might allow for resource theft, particularly if that block contains references.

 

Shared Variables

 

A Dominion object could also be used to store shared variables. For example, the owner of that dominion could be a user that would need to be notified - that user's UI would be a shared variable.

 

Keeping Dominion references secure

 

References to a Dominion object grant the holder to use resources in that dominion.

 

...thought: unless resource access to a dominion is granted by looking at the object's actual reference, by introspection, and then preventing that object from being able to modify its own dominion reference??

 

...thought: perhaps a dominion reference does not grant the holder to use resources?

 

Managing Dominions

 

The user would occasionally need to track down which dominions are using resources on his computer.

 

An audit of the entire image would need to be performed, perhaps using the garbage collector. This audit would involve querying every single object in the image about which dominion it belongs to. A list or tree of all dominions would be returned for the user to maintain.

 

Operations which could be invoked on a Dominion could be:

  • Adding or removing capabilities.
  • Destroying that dominion, removing all objects from this computer.
  • Adding child domininions.
  • Re-assinging objects to other dominions (?)

 

Generally, dominion management should be automated as far as possible. If a user decides to run a particular service, he will need to allocate resources to that dominion. If a browser-style UI is used, the dominion of whatever site is currently being visited can be allocated resources automatically and have those resources revoked when the user leaves that page (although some caching mechanism would be needed). Management would probably be done by parent dominions of the dominion which is being managed, and failing that then by the user.

 

XXX but a dominion might be granted resources by any other dominion, so the parent/child relationship doesn't really work.

 

Handling exceptions

 

What happens when the dominion's resources are exhausted?

 

  • The process which attempts to use more resources raises an exception, or is suspended (or both if that is possible - can you resume from a thrown exception?). When the resource shortage has been resolved, the process may continue.
  • Perhaps a representative object of the dominion could be asked to reduce resource usage when there is e.g. only 5% of resources left.

 

What happens when the dominion resources are reduced to below the limits set?

 

  • Perhaps some message could be sent to a representative object of the dominion asking it to reduce resources.
  • Deadlock may occur if the dominion needs to allocate more resources in order to reduce it's resource usage.

 

What happens when a dominion is forcefully removed?

 

  • All references to objects in that dominion are nullified... somehow. A primitive could be implemented to do this, or all objects in that dominion could have a becomeForward: performed on them. These objects could be replaced with a special instance of, for example, RemovedObject or InvalidObject.
  • All threads with objects from that dominion on their call stack will need to return or be terminated.
  • Before this happens, it would be polite to inform the dominion manager (and replication algorithms) that that dominion is about to be removed? If a dominion is well-behaved, it will be able to remove itself from a VM. If it is naughty, then that dominion will need to be forcefully removed.
  • What happens if the dominion has a lock on other objects, such as system resources? What happens if a dominion's code actually is deadlocked somewhere? Removing it won't resolve the deadlock...

 

Network security

 

A firewall could be implemented to disallow objects of private dominions to pass through it.

 

Multiple computers in a distributed system could share a dominion between themselves. Several computers could allocate resources to a particular dominion such that that dominion spans a cluster of computers.

 

[...] doRemotely. "Execute that block on any server in the current dominion."
aDominion storageService storeAnywhere: aByteArray id: anID redundancy: n. "Store that byte array into storage."

 

A dominion manager could be made which lets the user view/edit the total resources a dominion currently occupies, how much it has available, and the servers that a dominion has available to it.

 

If a user-defined dominion manager could be passed to each dominion before it is baked, then:

  • The dominion manager could handle workload information requests, such as #idle (please go find work), #busy (happy, but don't accept new work), #overloaded (remove work or be shut down). Somehow, there must be a way of specifying that work can be offloaded without causing task tennis.
  • The dominion manager could manage remote references to other dominions or job sharing objects.
  • The dominion manager could handle unhandled exceptions.
  • The dominion manager could handle lifecycle events: dominion created, dominion about to be destroyed, child added, etc.
  • When a new host grants privileges to a dominion, the dominion manager is brought over from a remote site and fired up with a lifecycle event.
  • Effectively, the dominion manager could contain all user-specified code.
  • Load balancing algorithms could be implemented using the DominionManager as a starting point.

Alternatively, perhaps Dominion objects could just need to implement a particular interface?

 

User-visible objects could be browsed in a hierarchy of dominions. Each user-visible object ("documents") would be a dominion in it's own right. Each dominion would have a "main object" which would be an object that returns an icon, responds to the "open" command etc. This object can be nil, in which case the dominion is just a dominion.

 

Using Dominions

 

SiteBrowser would allow the currently browsed Site particular resources locally. When the site is navigated away from (the site is passified), the resources it is granted are reduced to background status. Background processes must not spoil interactivity.The user should be able to choose how many resources a particular site is granted locally.

 

The user would be able to grant particular dominions resources on the local host.

 

A local network (or current ISP hosted) "accelerater" machine could provide resources for domains that users are using - i.e. the SiteBrowser would know that an accelerater machine is nearby and get that machine to grant resources to currently viewed dominions. In effect, the accelerator machine becomes part of the distributed network hosting objects that appear on Sites, depending on demand.

 

A user would be able to purchase hosting on one or more remote hosting services, and then assign those resources to particular dominions.

 

So... there are two ways that dominions are granted access to a local (or remote) computer:

  1. The user clicks on a Site.
  2. The user uses a manager application of some sort to allocate resources to a particular dominion.

 

When the user clicks on a Site:

  1. A reference to that Site's dominion is brought over as a distributed object. That dominion is then converted or blessed as a local dominion and is granted resources.
  2. The dominion manager of that dominion would probably have been brought over with that dominion during serialisation.
  3. That dominion is granted resources by the SiteBrowser, depending on what resources are available.
  4. The dominion manager of that dominion starts receiving lifecycle events.
  5. A reference to that Site is brought over as a distributed object and instantiated in that dominion.
  6. Some time after that Site has been navigated away from, the resources of that dominion are deallocated.

 

When a user adds resources to a dominion:

  1. Somehow, the user has received a request to add resources to a dominion. Maybe this is a special object? Maybe the user cuts and pastes, or drags and drops this dominion reference to his dominion manager.
  2. Using a dominion management application, the user adds that dominion as a child of, for example, "hosted dominions".
  3. The dominion manager of that dominion would have been brought over during object replication and serialisation. The dominion manager starts receiving lifecycle events.
  4. The dominion manager typically would have a reference to a central coordinator for that distributed dominion, or alternatively the dominion manager might be that distributed object. This would have the ability to run code on any remote host within that dominion.

 

 

Logging in

System objects would be part of a "local" dominion. This dominion is where system stuff happens: loading classes, saving images, scheduling processes.  Each of these would probably happen under their own dominions under the local dominion.

 

Dominions are granted resources by other dominions. Dominions can only grant resources that they themselves have. The local dominion would be the "master dominion" in that it controls all available resources. There needs to be some mechanism for granting a sub-dominion resources that its parent does not have; perhaps by asking a grandparent for those resources?

 

When a user inserts his identity key, the master dominion would grant resources to that user's dominion. Then, that user's dominion would in turn grant resources to each other dominion used by that user.

 

That user's dominion would grant resources to any sub-dominions that need them.

 

Allocation exhaustion

Dominions not descended from the user's dominion will not automatically be granted resources. It will start with zero resource allocations and the same process for allocation exhaustion will be followed as for dominions who have exceeded their allottment. Objects from the network will have this charactoristic.

 

When a dominion exceeds resources, there are several reasons:

  • It never had access to those resources in the first place (zero allocation).
  • It simply needs more resources to run (programmer underestimation).
  • It is out of control and must be suspended.
  • The user has denied resources; e.g. closing the browser window.

 

When a dominion runs out of resources, processes are suspended and that dominion's manager is notified. That manager might ask the user whether to grant more resources or kill that dominion.

 

Servers

A computer that is a server needs to allocate resources to a dominion. This would typically happen when a user asks for hosting.

 

The hosted dominion needs to know who the user is for notifications.

 

Some management application would be used to determine resource allocation. Typically a server (or its local/master dominion) would allocate all resources to a "hoster" dominion. Hosted dominions would be sub-dominions of that hoster dominion. This would be managed using some hosting application.

 

--> but can dominions have multiple parents? Say for example that a dominion is hosted in many places. What then?

 

Perhaps a dominion doesn't necessarily have a parent, but rather can be granted/denied resources by another dominion. When granted resources, the grant is persistent and the granter can deny resources at a later stage.

 

  • On a network, a distributed service might want to know about where other resources are available (i.e. dominions on remote servers). I'm not sure how this would work. Perhaps the dominion is made in response to that object's request to the user so that the dominion does not need to manage it's own broadcast trees etc.
  • Dominions could form an "Object LAN" such as a company's internal network for confidential information. Objects could restrict themselves to a particular dominion, and that dominion is closely guarded (e.g. any server in that dominion holds that dominion's private key to authenticate itself).  

 

 

Management of services

An administrator would be responsible for allocating resources on a distributed system.

 

Every computer would have a "local dominion". The local dominion on a particular computer is granted all resources on that computer, and can grant use of those resources to other dominions.

 

The administrator would likely partition the system using dominions for management. A pool of computers dedicated to a particular service would have their local dominions allocate all available resources to that service's dominion.

 

For example, a hosted site might be hosted by a network of computers across the Internet; the administrator would make a dominion for that site. Each computer in that pool would then be made to allocate resources to that dominion. When users visit that site, their browsers will also allocate resources to that dominion for the duration of their visit.

 

To ease administration, a hosting provider might make a master dominion to which all local dominions grant all resources by default. This master dominion would then grant/deny resources to individual Site or service dominions as required.

 

Management of a computer

When a computer is short on resources, administraters need to be able to determine where those resources are going.

 

A tool for determining where memory is allocated needs to be made.

Another tool for determining where CPU is allocated needs to be made.

 

When a dominion allocates resources to another dominion, the original dominion is also billed for when those resources are used. The tools would be able to then determine a hierarchy of dominions with each one allocating resources to other dominions; a tree structure would be able to show where resources are ultimately being spent (cf: xdu).

 

When the administrator sees a dominion, he can choose to change the resource allocations. Resource allocations can be a percentage of available resources or absolute amounts. Dominions are provided by the programmer with suggested resource allocations. Warnings would be shown if these allocations cannot be made.

 

When a dominion has its allocations reduced, and if that dominion has already allocated those resources (assuming memory and disk usage), then that dominion will not be able to allocate more resources until it is below its allocation again. The dominion would be notified that it is over its allocation, and special code might be run to ask that dominion to reduce resource usage. Typically this would happen when a dominion is asked to leave a computer.

 

If a dominion misbehaves and doesn't reduce its allocation, then that dominion can be forceably removed. Processes running on that dominion will have exceptions thrown (DominionDeallocatedException) until no further call stack frames are allocated to that dominion. Garbage will be collected, disk space reclaimed and any remaining references to objects in that dominion will be replaced with references to InvalidObject (or a ResourceDenied singleton?).

 

SiteBrowser

SiteBrowser would visit Sites. Each Site is a distributed object. Each Site would have an existing dominion that is assigned to it at creation; the dominion would be stored as an instance variable.

 

When a Site is interacted with, the following could happen:

  • The Site would react to events and process them. This includes the event that calls onDraw:.
  • The Site may fork more background processes to do work.

 

These are the basic requirements for dominion-based management:

 

  • When the Site is activated, the dominion that it resides in is granted resources by the SiteBrowser.
  • The Site's CPU usage would be scheduled according to the dominion's statistics.
  • The Site's memory usage is constrained by the dominion's statistics.
  • When the Site draws on the screen (a primitive), the CPU usage is also added to the dominion's statistics.
  • If the Site uses network or disk, these are done according to the dominion's statistics.
  • When the Site is no longer used, the dominion's privileges are revoked.

 

When a site is activated:

 

SiteBrowser>>activateSite: aSite
| d |
d := aSite dominion.  " Security alert: what happens if >>dominion is overridden? How about:"
" d := Dominion of: aSite "
dominions at: aSite put: d.
self grantResourcesTo: d.

 

It should not matter if an object overrides >>dominion; that object should not have access to other dominions.

 

When a site is deactivated:

 

SiteBrowser>>deactivateSite: aSite
self retractResourcesFrom: (dominions at: aSite). " Security problem: what if the site lies about its dominion? "
 

It might be necessary to keep track of which Site has which dominion.

 

Every invocation on the Site then needs to be put in a particular dominion. This could be done by every calling method:

 

SiteBrowser>>draw
self enterDominion: (self dominionForSite: currentSite).
[currentSite drawOn: screen] fork.
 

Alternatively:

 

SiteBrowser>>draw
[currentSite drawOn: screen] forkInDominion: (self dominionForSite: currentSite).

 

A dominion can only be exited when a stack frame returns.

 

However, this leave the problem of accidently invoking a method on aSite without first entering aSite's dominion. We could consider any such invocation to be a security risk. Alternatively, we could always run in a dominion with very limited privileges, and the Site receives more privileges than the calling thread. The latter is problematic:

SiteBrowser should receive more CPU time than its Sites, but does not need as much memory or extra resources.

 

Alternatively, a Site might have all methods invoked on a minimally enabled dominion, and it is the responsibility of the Site to hold a reference to its own dominion and to enter it.

 

Snapshotting

Implement:

 

Dominion>>snapshot

"On return, guarantees that a version of this dominion is snapshotted to disk. In Squeak, this will save the image. A version (object) of that dominion is returned."

 

Dominion>>restoreTo: version

"Restores this dominion to that version...? Or returns a new dominion? "

 

Dominion>>snapshots

"Returns the list of versions available. Distributed systems will want this. "

 

Issues

What does the scheduler do when it reschedules? A call stack could consist of many dominions; each element of the call stack is an object that is consuming memory and that consumed memory needs to be added and removed from that dominion.

 

  • Perhaps at scheduling time, a call stack can be measured up. If it is large (or growing, or something), then memory allocation can be tallied up.

 

Invocation of class-side methods and primitives should be transparent to dominions; the dominion that is billed for its resource usage is found by iterating down through the stack until a dominioned object is found.

 

  • Perhaps the object heirarchy could have dominioned objects and non-dominioned objects (e.g. SmallInteger and Classes). Non-dominioned objects are transparent and cause a search down through the call stack.

 

Possible attacks

  • Sometimes methods are run in the dominion of whatever invoked them. Examples include SmallInteger, Class and class-side methods, where the dominion can't be stored in the object. SmallInteger and Class could potentially be sub-classed, allowing resource theft.
  • Class-side methods run in the dominion of their invoker. This could allow for resource theft.
  • Dominion instances must also have dominions to prevent too many dominions being made (limits enforced by memory constraints). Care must be taken when finding the current dominion (e.g. when dominions have a hierarchy) to prevent too much resource use when doing dominion accounting. Potentially, an attacker could make a large number of nested dominions, which would occupy the scheduler as it tries to do resource management on them. This could be circumvented if the accounting work was allocated inside the dominion's resources.
  • Blocks could cause problems. Which dominion is charged for the invocation of somebody else's block? 

 

Comments (0)

You don't have permission to comment on this page.