On Fri, 2010-09-10 at 17:00 +0100, Daniel P. Berrange wrote:
/**
* virLockManager:
*
* A lock manager is a process that will supervise another
* process. It will obtain & hold locks/leases for resources
* the supervised process uses
*/
typedef struct virLockManager virLockManager;
typedef virLockManager *virLockManagerPtr;
typedef enum {
VIR_LOCK_MANAGER_RESOURCE_READONLY = (1 << 0),
VIR_LOCK_MANAGER_RESOURCE_SHARED = (1 << 1),
} virLockManagerResourceFlags;
enum {
VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK = 0,
} virLockManagerResourceType;
enum {
VIR_LOCK_MANAGER_NEW_DOMAIN = 0,
} virLockManagerNewType;
enum {
VIR_LOCK_MANAGER_NEW_MIGRATE = (1 << 0),
VIR_LOCK_MANAGER_NEW_ATTACH = (1 << 1),
} virLockManagerNewFlags;
enum {
VIR_LOCK_MANAGER_MIGRATE_CANCEL = (1 << 0);
} virLockManagerCompleteMigrateFlags;
/**
* virLockManagerNew:
* @driver: the driver implementation to use
* @type: the type of process to be supervised
* @flags: one of virLockManagerNewFlags
*
* Create a new context to supervise a process, usually
* a virtual machine. For a normal startup, flags can
* be 0. For incoming migration, use VIR_LOCK_MANAGER_NEW_MIGRATE
*
* Returns a new lock manager context
*/
virLockManagerPtr virLockManagerNew(virLockManagerDriverPtr driver,
unsigned int type,
unsigned int flags);
/**
* virLockManagerSetParameter:
* @manager: the lock manager context
* @key: the parameter name
* @value: the parameter value
*
* Set a configuration parameter for the managed process.
* A process of VIR_LOCK_MANAGER_START_DOMAIN will be
* given at least 3 parameters:
*
* - id: the domain unique id
* - uuid: the domain uuid
* - name: the domain name
*
* There may be other parameters specific to the lock manager
* plugin that are provided for the managed process
*
* This should only be called prior to the supervised process
* being started. Setting parameters may change the set of
* argv returned by virLockManagerGetSupervisorArgs.
*/
int virLockManagerSetParameter(virLockManagerPtr manager,
const char *key,
const char *value);
/**
* virLockManagerRegisterResource:
* @manager: the lock manager context
* @type: the resource type virLockManagerResourceType
* @name: the resource name
* @flags: the resource access flags
*
* Register a resource that is required when the process
* starts up. This may only be called prior to the process
* being started. The format of @name varies according to
* the resource @type. A VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK
* will have a fully qualified file path.
*
* If no flags are given, the resource is assumed to be
* used in exclusive, read-write mode. Access can be
* relaxed to readonly, or shared read-write.
*/
int virLockManagerRegisterResource(virLockManagerPtr manager,
unsigned int type,
const gchar *name,
unsigned int flags);
/**
* virLockManagerAcquireResource:
* @manager: the lock manager context
* @type: the resource type virLockManagerResourceType
* @name: the resource name
* @flags: the resource access flags
*
* Dynamically acquire a resource for a running process.
* This may only be called once the process has been
* started. The format of @name varies according to
* the resource @type. A VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK
* will have a fully qualified file path.
*
* If no flags are given, the resource is assumed to be
* used in exclusive, read-write mode. Access can be
* relaxed to readonly, or shared read-write.
*/
int virLockManagerAcquireResource(virLockManagerPtr manager,
const gchar *file,
unsigned int flags);
/**
* virLockManagerReleaseResource:
* @manager: the lock manager context
* @type: the resource type virLockManagerResourceType
* @name: the resource name
* @flags: the resource access flags
*
* Dynamically release a resource for a running process.
* This may only be called after the process has been
* started. The format of @name varies according to
* the resource @type. A VIR_LOCK_MANAGER_RESOURCE_TYPE_DISK
* will have a fully qualified file path.
*
* If no flags are given, the resource is assumed to be
* used in exclusive, read-write mode. Access can be
* relaxed to readonly, or shared read-write.
*/
int virLockManagerReleaseResource(virLockManagerPtr manager,
const gchar *file,
unsigned int flags);
/**
* virLockManager:
* @manager: the lock manager context
*
* Retrieve the path of the supervisor binary
*/
char *virLockManagerGetSupervisorPath(virLockManagerPtr manager);
/**
* virLockManager:
* @manager: the lock manager context
*
* Retrieve the security context of the supervisor binary
*/
char *virLockManagerGetSupervisorContext(virLockManagerPtr manager);
/**
* virLockManager:
* @manager: the lock manager context
* @argv: returned argument values
* @argc: returned argument count
*
* Retrieve custom argv to pass to the supervisor binary
* ahead of the normal process binary & argv. It is recommended
* that the last argv be '--' to allow reliable determination
* of the last supervisor arg.
*/
int virLockManagerGetSupervisorArgs(virLockManagerPtr manager,
char ***argv,
int *argc,
unsigned int flags);
/**
* virLockManagerPrepareMigrate:
* @manager: the lock manager context
* @targetURI: destination of the migration
*
* Notify the supevisor that the process is about to be migrated
* to another host at @targetURI
*/
[SM] I don't think migration is a topic that should be managed in the
lock level. Further more in sync_manager's case there are situation
where you cannot perform a clean handover (like when the source host
looses connection to the storage and we are migrating to another host to
solve this).
As I stated in my previous e-mail you think that lock handover is a
needlessly complex use case to have a special algorithm for in
sync_manager. Just releasing in the source side and reacquiring on the
target (and making sure no one got in the middle) before starting the
migration is simpler.
You could put it in a special verb for handovers that implements this
logic but I don't think it should be in the lock API but rather in a
higher API level
int virLockManagerPrepareMigrate(virLockManagerPtr manager,
const char *targetURI,
unsigned int flags);
/**
* virLockManagerCompleteMigrateIn:
* @manager: the lock manager context
* @sourceURI: the origin of the migration
*
* Notify the supervisor that the process has completed
* migration. If the migration is aborted, then the @flags
* should be VIR_LOCK_MANAGER_MIGRATE_CANCEL
*/
int virLockManagerCompleteMigrateIn(virLockManagerPtr manager,
const char *sourceURI,
unsigned int flags);
/**
* virLockManagerCompleteMigrateOut:
* @manager: the lock manager context
* @targetURI: the destination of the migration
*
* Notify the supervisor that the process has completed
* migration. If the migration is aborted, then the @flags
* should be VIR_LOCK_MANAGER_MIGRATE_CANCEL
*/
int virLockManagerCompleteMigrateOut(virLockManagerPtr manager,
const char *targetURI,
unsigned int flags);
/**
* virLockManagerGetChild:
* @manager: the lock manager context
*
* Obtain the PID of the managed process
*/
int virLockManagerGetChild(virLockManagerPtr manager,
pid_t *pid,
unsigned int flags);
/**
* virLockManager:
* @manager: the lock manager context
*
* Inform the supervisor that the supervised process has
* been, or can be stopped.
*/
int virLockManagerShutdown(virLockManagerPtr manager,
unsigned int flags);
/**
* virLockManager:
* @manager: the lock manager context
*
* Release resources. If the supervised process is still
* running, it will be killed with prejudice
*/
void virLockManagerFree(virLockManagerPtr manager);