2001-10-09 16:05:34 +00:00
/*
* Copyright ( C ) 2001 Sistina Software ( UK ) Limited .
*
2001-10-31 12:47:01 +00:00
* This file is released under the LGPL .
2001-10-09 16:05:34 +00:00
*/
2001-10-16 16:25:28 +00:00
# include "metadata.h"
2001-10-09 16:05:34 +00:00
# include "activate.h"
2001-11-15 14:27:51 +00:00
# include "display.h"
2001-11-02 16:28:04 +00:00
# include "log.h"
2001-11-12 12:20:58 +00:00
# include "fs.h"
2001-12-31 19:09:51 +00:00
# include "lvm-string.h"
2002-02-25 12:56:16 +00:00
# include "pool.h"
# include "toolcontext.h"
2002-02-26 11:49:17 +00:00
# include "dev_manager.h"
2002-01-21 11:06:32 +00:00
2002-03-05 20:03:09 +00:00
/* FIXME Temporary */
# include "vgcache.h"
2002-01-21 11:06:32 +00:00
# include <limits.h>
2002-02-12 11:15:45 +00:00
# include <linux/kdev_t.h>
2002-02-18 15:52:48 +00:00
# include <fcntl.h>
2002-01-21 11:06:32 +00:00
2002-02-11 15:48:34 +00:00
# define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
2001-10-09 16:05:34 +00:00
2002-01-17 16:39:24 +00:00
int library_version ( char * version , size_t size )
{
if ( ! dm_get_library_version ( version , size ) )
return 0 ;
return 1 ;
}
int driver_version ( char * version , size_t size )
{
int r = 0 ;
struct dm_task * dmt ;
log_very_verbose ( " Getting driver version " ) ;
if ( ! ( dmt = dm_task_create ( DM_DEVICE_VERSION ) ) ) {
stack ;
return 0 ;
}
if ( ! dm_task_run ( dmt ) )
log_error ( " Failed to get driver version " ) ;
if ( ! dm_task_get_driver_version ( dmt , version , size ) )
goto out ;
r = 1 ;
2002-03-18 23:25:50 +00:00
out :
2002-01-17 16:39:24 +00:00
dm_task_destroy ( dmt ) ;
return r ;
}
2002-02-26 11:49:17 +00:00
/*
* Returns 1 if info structure populated , else 0 on failure .
*/
int lv_info ( struct logical_volume * lv , struct dm_info * info )
2001-11-07 11:51:42 +00:00
{
2002-02-26 11:49:17 +00:00
int r ;
struct dev_manager * dm ;
2002-01-10 23:21:07 +00:00
2002-02-26 11:49:17 +00:00
if ( ! ( dm = dev_manager_create ( lv - > vg - > name ) ) ) {
2002-01-21 11:06:32 +00:00
stack ;
2002-02-26 11:49:17 +00:00
return 0 ;
2002-01-21 11:06:32 +00:00
}
2002-01-10 23:21:07 +00:00
2002-02-26 11:49:17 +00:00
if ( ! ( r = dev_manager_info ( dm , lv , info ) ) )
stack ;
2002-01-10 23:21:07 +00:00
2002-02-26 11:49:17 +00:00
dev_manager_destroy ( dm ) ;
return r ;
}
2002-02-11 17:42:02 +00:00
2002-05-09 21:17:57 +00:00
/*
* Returns 1 if percent set , else 0 on failure .
*/
2002-05-22 14:03:45 +00:00
int lv_snapshot_percent ( struct logical_volume * lv , float * percent )
2002-05-09 21:17:57 +00:00
{
int r ;
struct dev_manager * dm ;
if ( ! ( dm = dev_manager_create ( lv - > vg - > name ) ) ) {
stack ;
return 0 ;
}
2002-05-22 14:03:45 +00:00
if ( ! ( r = dev_manager_snapshot_percent ( dm , lv , percent ) ) )
2002-05-09 21:17:57 +00:00
stack ;
2002-05-22 14:03:45 +00:00
2002-05-09 21:17:57 +00:00
dev_manager_destroy ( dm ) ;
return r ;
}
2002-03-11 19:02:28 +00:00
static int _lv_active ( struct logical_volume * lv )
2001-11-07 15:02:07 +00:00
{
2002-02-26 11:49:17 +00:00
struct dm_info info ;
2001-11-07 15:02:07 +00:00
2002-02-26 11:49:17 +00:00
if ( ! lv_info ( lv , & info ) ) {
2001-11-07 15:02:07 +00:00
stack ;
2002-02-26 11:49:17 +00:00
return - 1 ;
2001-11-07 15:02:07 +00:00
}
2002-02-26 11:49:17 +00:00
return info . exists ;
2001-11-07 15:02:07 +00:00
}
2002-03-11 19:02:28 +00:00
static int _lv_open_count ( struct logical_volume * lv )
2002-02-18 15:52:48 +00:00
{
2002-02-26 11:49:17 +00:00
struct dm_info info ;
2002-02-18 15:52:48 +00:00
2002-02-26 11:49:17 +00:00
if ( ! lv_info ( lv , & info ) ) {
2002-02-18 15:52:48 +00:00
stack ;
2002-02-26 11:49:17 +00:00
return - 1 ;
2002-02-18 15:52:48 +00:00
}
2002-02-26 11:49:17 +00:00
return info . open_count ;
2002-02-18 15:52:48 +00:00
}
2002-03-01 19:08:11 +00:00
/* FIXME Need to detect and handle an lv rename */
2002-03-11 15:08:39 +00:00
static int _lv_activate ( struct logical_volume * lv )
2001-10-09 16:05:34 +00:00
{
2002-02-11 15:48:34 +00:00
int r ;
2002-02-26 11:49:17 +00:00
struct dev_manager * dm ;
2001-10-09 16:05:34 +00:00
2002-02-26 11:49:17 +00:00
if ( ! ( dm = dev_manager_create ( lv - > vg - > name ) ) ) {
2002-02-11 15:48:34 +00:00
stack ;
return 0 ;
2001-11-02 13:45:05 +00:00
}
2002-03-07 16:48:46 +00:00
if ( ! ( r = dev_manager_activate ( dm , lv ) ) )
2002-02-11 15:48:34 +00:00
stack ;
2001-11-02 13:45:05 +00:00
2002-02-26 11:49:17 +00:00
dev_manager_destroy ( dm ) ;
2001-11-02 13:45:05 +00:00
return r ;
2001-10-09 16:05:34 +00:00
}
2001-10-16 16:25:28 +00:00
2002-03-11 15:08:39 +00:00
static int _lv_deactivate ( struct logical_volume * lv )
2001-10-31 17:59:52 +00:00
{
2002-02-26 11:49:17 +00:00
int r ;
struct dev_manager * dm ;
2001-11-07 11:51:42 +00:00
2002-02-26 11:49:17 +00:00
if ( ! ( dm = dev_manager_create ( lv - > vg - > name ) ) ) {
2002-02-11 15:48:34 +00:00
stack ;
return 0 ;
}
2001-11-07 11:51:42 +00:00
2002-02-26 11:49:17 +00:00
if ( ! ( r = dev_manager_deactivate ( dm , lv ) ) )
2001-11-07 11:51:42 +00:00
stack ;
2002-02-26 11:49:17 +00:00
dev_manager_destroy ( dm ) ;
return r ;
2001-11-07 11:51:42 +00:00
}
2002-03-11 15:08:39 +00:00
static int _lv_suspend ( struct logical_volume * lv )
2002-01-10 23:21:07 +00:00
{
2002-03-14 15:36:07 +00:00
int r ;
struct dev_manager * dm ;
2001-11-28 18:03:11 +00:00
2002-03-14 15:36:07 +00:00
if ( ! ( dm = dev_manager_create ( lv - > vg - > name ) ) ) {
2001-11-07 11:51:42 +00:00
stack ;
return 0 ;
}
2001-10-31 17:59:52 +00:00
2002-03-14 15:36:07 +00:00
if ( ! ( r = dev_manager_suspend ( dm , lv ) ) )
2001-11-07 11:51:42 +00:00
stack ;
2001-10-31 17:59:52 +00:00
2002-03-14 15:36:07 +00:00
dev_manager_destroy ( dm ) ;
return r ;
2002-02-11 15:48:34 +00:00
}
2002-01-10 23:21:07 +00:00
2002-03-01 19:08:11 +00:00
/*
* These two functions return the number of LVs in the state ,
* or - 1 on error .
*/
2001-11-02 16:28:04 +00:00
int lvs_in_vg_activated ( struct volume_group * vg )
{
2001-11-07 11:51:42 +00:00
struct list * lvh ;
struct logical_volume * lv ;
2001-11-08 16:15:58 +00:00
int count = 0 ;
2001-11-07 11:51:42 +00:00
list_iterate ( lvh , & vg - > lvs ) {
2002-01-21 16:49:32 +00:00
lv = list_item ( lvh , struct lv_list ) - > lv ;
2002-03-11 19:02:28 +00:00
count + = ( _lv_active ( lv ) = = 1 ) ;
2001-11-07 11:51:42 +00:00
}
return count ;
2001-11-02 16:28:04 +00:00
}
2001-11-07 15:02:07 +00:00
int lvs_in_vg_opened ( struct volume_group * vg )
{
struct list * lvh ;
struct logical_volume * lv ;
2001-11-08 16:15:58 +00:00
int count = 0 ;
2001-11-07 15:02:07 +00:00
list_iterate ( lvh , & vg - > lvs ) {
2002-01-21 16:49:32 +00:00
lv = list_item ( lvh , struct lv_list ) - > lv ;
2002-03-11 19:02:28 +00:00
count + = ( _lv_open_count ( lv ) = = 1 ) ;
2001-11-07 15:02:07 +00:00
}
return count ;
}
2002-02-25 12:56:16 +00:00
2002-02-26 11:49:17 +00:00
static struct logical_volume * _lv_from_lvid ( struct cmd_context * cmd ,
2002-03-05 20:03:09 +00:00
const char * lvid_s )
2002-02-25 12:56:16 +00:00
{
struct lv_list * lvl ;
struct volume_group * vg ;
2002-03-05 20:03:09 +00:00
union lvid * lvid ;
2002-02-25 12:56:16 +00:00
2002-03-05 20:03:09 +00:00
lvid = ( union lvid * ) lvid_s ;
2002-04-24 18:20:51 +00:00
log_very_verbose ( " Finding volume group for uuid %s " , lvid_s ) ;
if ( ! ( vg = vg_read_by_vgid ( cmd , lvid - > id [ 0 ] . uuid ) ) ) {
2002-03-05 20:03:09 +00:00
log_error ( " Volume group for uuid not found: %s " , lvid_s ) ;
2002-02-25 12:56:16 +00:00
return NULL ;
}
2002-04-24 18:20:51 +00:00
log_verbose ( " Found volume group \" %s \" " , vg - > name ) ;
2002-02-25 12:56:16 +00:00
if ( vg - > status & EXPORTED_VG ) {
2002-04-24 18:20:51 +00:00
log_error ( " Volume group \" %s \" is exported " , vg - > name ) ;
2002-02-25 12:56:16 +00:00
return NULL ;
}
2002-03-05 20:03:09 +00:00
if ( ! ( lvl = find_lv_in_vg_by_lvid ( vg , lvid ) ) ) {
log_very_verbose ( " Can't find logical volume id %s " , lvid_s ) ;
2002-02-25 12:56:16 +00:00
return NULL ;
}
return lvl - > lv ;
}
2002-03-14 15:36:07 +00:00
/* These return success if the device is not active */
2002-03-05 20:03:09 +00:00
int lv_suspend_if_active ( struct cmd_context * cmd , const char * lvid_s )
2002-02-25 12:56:16 +00:00
{
struct logical_volume * lv ;
2002-03-11 19:02:28 +00:00
struct dm_info info ;
2002-02-25 12:56:16 +00:00
2002-03-05 20:03:09 +00:00
if ( ! ( lv = _lv_from_lvid ( cmd , lvid_s ) ) )
2002-02-25 12:56:16 +00:00
return 0 ;
2002-03-14 15:36:07 +00:00
if ( test_mode ( ) ) {
_skip ( " Suspending '%s'. " , lv - > name ) ;
return 0 ;
}
2002-03-18 23:25:50 +00:00
if ( ! lv_info ( lv , & info ) ) {
stack ;
return 0 ;
}
2002-03-11 19:02:28 +00:00
if ( info . exists & & ! info . suspended )
2002-04-11 09:14:04 +00:00
return _lv_suspend ( lv ) ;
2002-03-01 19:08:11 +00:00
2002-02-25 12:56:16 +00:00
return 1 ;
}
2002-03-05 20:03:09 +00:00
int lv_resume_if_active ( struct cmd_context * cmd , const char * lvid_s )
2002-02-25 12:56:16 +00:00
{
struct logical_volume * lv ;
2002-03-11 19:02:28 +00:00
struct dm_info info ;
2002-02-25 12:56:16 +00:00
2002-03-05 20:03:09 +00:00
if ( ! ( lv = _lv_from_lvid ( cmd , lvid_s ) ) )
2002-02-25 12:56:16 +00:00
return 0 ;
2002-03-14 15:36:07 +00:00
if ( test_mode ( ) ) {
_skip ( " Resuming '%s'. " , lv - > name ) ;
return 0 ;
}
2002-03-18 23:25:50 +00:00
if ( ! lv_info ( lv , & info ) ) {
stack ;
return 0 ;
}
2002-03-11 19:02:28 +00:00
if ( info . exists & & info . suspended )
2002-04-11 09:14:04 +00:00
return _lv_activate ( lv ) ;
2002-02-25 12:56:16 +00:00
return 1 ;
}
2002-03-11 15:08:39 +00:00
int lv_deactivate ( struct cmd_context * cmd , const char * lvid_s )
2002-02-27 12:26:41 +00:00
{
struct logical_volume * lv ;
2002-03-11 19:02:28 +00:00
struct dm_info info ;
2002-02-27 12:26:41 +00:00
2002-03-05 20:03:09 +00:00
if ( ! ( lv = _lv_from_lvid ( cmd , lvid_s ) ) )
2002-02-27 12:26:41 +00:00
return 0 ;
2002-03-14 15:36:07 +00:00
if ( test_mode ( ) ) {
_skip ( " Deactivating '%s'. " , lv - > name ) ;
return 0 ;
}
2002-03-18 23:25:50 +00:00
if ( ! lv_info ( lv , & info ) ) {
stack ;
return 0 ;
}
2002-03-11 19:02:28 +00:00
if ( info . exists )
2002-04-11 09:14:04 +00:00
return _lv_deactivate ( lv ) ;
2002-02-27 12:26:41 +00:00
return 1 ;
}
2002-03-11 15:08:39 +00:00
int lv_activate ( struct cmd_context * cmd , const char * lvid_s )
2002-02-27 12:26:41 +00:00
{
struct logical_volume * lv ;
2002-03-11 19:02:28 +00:00
struct dm_info info ;
2002-02-27 12:26:41 +00:00
2002-03-05 20:03:09 +00:00
if ( ! ( lv = _lv_from_lvid ( cmd , lvid_s ) ) )
2002-02-27 12:26:41 +00:00
return 0 ;
2002-03-14 15:36:07 +00:00
if ( test_mode ( ) ) {
_skip ( " Activating '%s'. " , lv - > name ) ;
return 0 ;
}
2002-03-18 23:25:50 +00:00
if ( ! lv_info ( lv , & info ) ) {
stack ;
return 0 ;
}
2002-03-01 19:08:11 +00:00
2002-03-11 19:02:28 +00:00
if ( ! info . exists | | info . suspended )
2002-04-11 09:14:04 +00:00
return _lv_activate ( lv ) ;
2002-02-27 12:26:41 +00:00
return 1 ;
}