2002-02-12 19:31:31 +03:00
/*
2004-03-30 23:35:44 +04:00
* Copyright ( C ) 2002 - 2004 Sistina Software , Inc . All rights reserved .
* Copyright ( C ) 2004 Red Hat , Inc . All rights reserved .
2002-02-12 19:31:31 +03:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
* of the GNU General Public License v .2 .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
2002-02-12 19:31:31 +03:00
*/
2002-11-18 17:04:08 +03:00
# include "lib.h"
2002-02-12 19:31:31 +03:00
# include "metadata.h"
# include "toolcontext.h"
2002-12-20 02:25:55 +03:00
int lv_is_origin ( const struct logical_volume * lv )
2002-02-12 19:31:31 +03:00
{
struct list * slh ;
struct snapshot * s ;
2002-04-24 22:20:51 +04:00
list_iterate ( slh , & lv - > vg - > snapshots ) {
2002-02-12 19:31:31 +03:00
s = list_item ( slh , struct snapshot_list ) - > snapshot ;
if ( s - > origin = = lv )
return 1 ;
}
return 0 ;
}
2002-12-20 02:25:55 +03:00
int lv_is_cow ( const struct logical_volume * lv )
2002-02-12 19:31:31 +03:00
{
struct list * slh ;
struct snapshot * s ;
2002-04-24 22:20:51 +04:00
list_iterate ( slh , & lv - > vg - > snapshots ) {
2002-02-12 19:31:31 +03:00
s = list_item ( slh , struct snapshot_list ) - > snapshot ;
if ( s - > cow = = lv )
return 1 ;
}
return 0 ;
}
2002-12-20 02:25:55 +03:00
struct snapshot * find_origin ( const struct logical_volume * lv )
2002-04-24 22:20:51 +04:00
{
struct list * slh ;
struct snapshot * s ;
list_iterate ( slh , & lv - > vg - > snapshots ) {
s = list_item ( slh , struct snapshot_list ) - > snapshot ;
if ( s - > origin = = lv )
return s ;
}
return NULL ;
}
2002-12-20 02:25:55 +03:00
struct snapshot * find_cow ( const struct logical_volume * lv )
2002-02-21 13:16:33 +03:00
{
struct list * slh ;
struct snapshot * s ;
2002-04-24 22:20:51 +04:00
list_iterate ( slh , & lv - > vg - > snapshots ) {
2002-02-21 13:16:33 +03:00
s = list_item ( slh , struct snapshot_list ) - > snapshot ;
if ( s - > cow = = lv )
return s ;
}
return NULL ;
}
2002-12-20 02:25:55 +03:00
struct list * find_snapshots ( const struct logical_volume * lv )
2002-05-08 20:57:46 +04:00
{
struct list * slh ;
struct list * snaplist ;
2002-05-31 23:28:37 +04:00
struct snapshot * s ;
struct snapshot_list * newsl ;
2002-05-08 20:57:46 +04:00
struct pool * mem = lv - > vg - > cmd - > mem ;
2002-05-09 16:03:55 +04:00
2002-05-08 20:57:46 +04:00
if ( ! ( snaplist = pool_alloc ( mem , sizeof ( * snaplist ) ) ) ) {
log_error ( " snapshot name list allocation failed " ) ;
return NULL ;
}
list_init ( snaplist ) ;
list_iterate ( slh , & lv - > vg - > snapshots ) {
2002-05-31 23:28:37 +04:00
s = list_item ( slh , struct snapshot_list ) - > snapshot ;
if ( ! ( s - > origin = = lv ) )
2002-05-09 16:03:55 +04:00
continue ;
if ( ! ( newsl = pool_alloc ( mem , sizeof ( * newsl ) ) ) ) {
log_error ( " snapshot_list structure allocation failed " ) ;
pool_free ( mem , snaplist ) ;
return NULL ;
2002-05-08 20:57:46 +04:00
}
2002-05-31 23:28:37 +04:00
newsl - > snapshot = s ;
2002-05-09 16:03:55 +04:00
list_add ( snaplist , & newsl - > list ) ;
2002-05-08 20:57:46 +04:00
}
return snaplist ;
}
2002-02-21 21:31:48 +03:00
int vg_add_snapshot ( struct logical_volume * origin ,
2002-02-12 19:31:31 +03:00
struct logical_volume * cow ,
2002-11-18 17:04:08 +03:00
int persistent , struct id * id , uint32_t chunk_size )
2002-02-12 19:31:31 +03:00
{
struct snapshot * s ;
struct snapshot_list * sl ;
2002-02-21 21:31:48 +03:00
struct pool * mem = origin - > vg - > cmd - > mem ;
2002-02-12 19:31:31 +03:00
/*
* Is the cow device already being used ?
*/
2002-02-20 22:04:55 +03:00
if ( lv_is_cow ( cow ) ) {
2002-02-12 19:31:31 +03:00
log_err ( " '%s' is already in use as a snapshot. " , cow - > name ) ;
return 0 ;
}
if ( ! ( s = pool_alloc ( mem , sizeof ( * s ) ) ) ) {
stack ;
return 0 ;
}
s - > persistent = persistent ;
s - > chunk_size = chunk_size ;
s - > origin = origin ;
s - > cow = cow ;
2002-11-18 17:04:08 +03:00
if ( id )
s - > id = * id ;
else if ( ! id_create ( & s - > id ) ) {
log_error ( " Snapshot UUID creation failed " ) ;
return 0 ;
}
2002-02-12 19:31:31 +03:00
if ( ! ( sl = pool_alloc ( mem , sizeof ( * sl ) ) ) ) {
stack ;
pool_free ( mem , s ) ;
return 0 ;
}
2002-11-18 17:04:08 +03:00
cow - > status & = ~ VISIBLE_LV ;
2002-02-12 19:31:31 +03:00
sl - > snapshot = s ;
2002-02-21 21:31:48 +03:00
list_add ( & origin - > vg - > snapshots , & sl - > list ) ;
2002-12-06 01:30:39 +03:00
origin - > vg - > snapshot_count + + ;
2002-02-12 19:31:31 +03:00
return 1 ;
}
int vg_remove_snapshot ( struct volume_group * vg , struct logical_volume * cow )
{
struct list * slh ;
struct snapshot_list * sl ;
2002-04-24 22:20:51 +04:00
list_iterate ( slh , & vg - > snapshots ) {
2002-02-12 19:31:31 +03:00
sl = list_item ( slh , struct snapshot_list ) ;
if ( sl - > snapshot - > cow = = cow ) {
list_del ( slh ) ;
2002-12-06 01:30:39 +03:00
vg - > snapshot_count - - ;
2002-02-12 19:31:31 +03:00
return 1 ;
}
}
/* fail */
2002-02-13 14:43:29 +03:00
log_err ( " Asked to remove an unknown snapshot. " ) ;
2002-02-12 19:31:31 +03:00
return 0 ;
}