2010-01-23 03:52:57 +03:00
/*-*- Mode: C; c-basic-offset: 8 -*-*/
2010-02-03 15:03:47 +03:00
/***
This file is part of systemd .
Copyright 2010 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
systemd is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
General Public License for more details .
You should have received a copy of the GNU General Public License
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
2010-04-18 05:07:42 +04:00
# include <errno.h>
2010-01-26 23:39:06 +03:00
# include "unit.h"
2010-01-23 03:52:57 +03:00
# include "snapshot.h"
2010-04-18 05:07:42 +04:00
# include "unit-name.h"
# include "dbus-snapshot.h"
static const UnitActiveState state_translation_table [ _SNAPSHOT_STATE_MAX ] = {
[ SNAPSHOT_DEAD ] = UNIT_INACTIVE ,
[ SNAPSHOT_ACTIVE ] = UNIT_ACTIVE
} ;
static const char * const state_string_table [ _SNAPSHOT_STATE_MAX ] = {
[ SNAPSHOT_DEAD ] = " dead " ,
[ SNAPSHOT_ACTIVE ] = " active "
} ;
static int snapshot_load ( Unit * u ) {
Iterator i ;
Unit * other ;
int r ;
assert ( u ) ;
HASHMAP_FOREACH ( other , u - > meta . manager - > units , i ) {
2010-01-23 03:52:57 +03:00
2010-04-18 05:07:42 +04:00
if ( UNIT_VTABLE ( other ) - > no_snapshots )
continue ;
if ( ( r = unit_add_dependency ( u , UNIT_REQUIRES , other ) ) < 0 )
return r ;
if ( ( r = unit_add_dependency ( u , UNIT_AFTER , other ) ) < 0 )
return r ;
}
u - > meta . load_state = UNIT_LOADED ;
return 0 ;
}
static void snapshot_dump ( Unit * u , FILE * f , const char * prefix ) {
2010-01-26 23:39:06 +03:00
Snapshot * s = SNAPSHOT ( u ) ;
2010-01-23 03:52:57 +03:00
assert ( s ) ;
2010-04-18 05:07:42 +04:00
assert ( f ) ;
2010-01-23 03:52:57 +03:00
2010-04-18 05:07:42 +04:00
fprintf ( f ,
" %sSnapshot State: %s \n "
" %sClean Up: %s \n " ,
prefix , state_string_table [ s - > state ] ,
prefix , yes_no ( s - > cleanup ) ) ;
}
static void snapshot_set_state ( Snapshot * s , SnapshotState state ) {
SnapshotState old_state ;
assert ( s ) ;
old_state = s - > state ;
s - > state = state ;
if ( state ! = old_state )
log_debug ( " %s changed %s → %s " , UNIT ( s ) - > meta . id , state_string_table [ old_state ] , state_string_table [ state ] ) ;
unit_notify ( UNIT ( s ) , state_translation_table [ old_state ] , state_translation_table [ state ] ) ;
}
static int snapshot_start ( Unit * u ) {
Snapshot * s = SNAPSHOT ( u ) ;
assert ( s ) ;
assert ( s - > state = = SNAPSHOT_DEAD ) ;
snapshot_set_state ( s , SNAPSHOT_ACTIVE ) ;
if ( s - > cleanup )
unit_add_to_cleanup_queue ( u ) ;
return 0 ;
}
static int snapshot_stop ( Unit * u ) {
Snapshot * s = SNAPSHOT ( u ) ;
assert ( s ) ;
assert ( s - > state = = SNAPSHOT_ACTIVE ) ;
snapshot_set_state ( s , SNAPSHOT_DEAD ) ;
return 0 ;
2010-01-23 03:52:57 +03:00
}
2010-01-26 23:39:06 +03:00
static UnitActiveState snapshot_active_state ( Unit * u ) {
2010-04-18 05:07:42 +04:00
assert ( u ) ;
return state_translation_table [ SNAPSHOT ( u ) - > state ] ;
}
static const char * snapshot_sub_state_to_string ( Unit * u ) {
assert ( u ) ;
return state_string_table [ SNAPSHOT ( u ) - > state ] ;
}
int snapshot_create ( Manager * m , const char * name , bool cleanup , Snapshot * * _s ) {
Unit * u ;
char * n = NULL ;
int r ;
assert ( m ) ;
assert ( _s ) ;
if ( name ) {
if ( ! unit_name_is_valid ( name ) )
return - EINVAL ;
if ( unit_name_to_type ( name ) ! = UNIT_SNAPSHOT )
return - EINVAL ;
if ( manager_get_unit ( m , name ) )
return - EEXIST ;
} else {
for ( ; ; ) {
if ( asprintf ( & n , " snapshot-%u.snapshot " , + + m - > n_snapshots ) < 0 )
return - ENOMEM ;
if ( ! manager_get_unit ( m , n ) )
break ;
free ( n ) ;
}
name = n ;
}
r = manager_load_unit ( m , name , NULL , & u ) ;
free ( n ) ;
if ( r < 0 )
return r ;
SNAPSHOT ( u ) - > cleanup = cleanup ;
* _s = SNAPSHOT ( u ) ;
return 0 ;
}
void snapshot_remove ( Snapshot * s ) {
assert ( s ) ;
unit_add_to_cleanup_queue ( UNIT ( s ) ) ;
2010-01-26 06:18:44 +03:00
}
2010-01-26 23:39:06 +03:00
const UnitVTable snapshot_vtable = {
2010-01-23 03:52:57 +03:00
. suffix = " .snapshot " ,
2010-04-18 05:07:42 +04:00
. no_alias = true ,
. no_instances = true ,
. no_snapshots = true ,
. load = snapshot_load ,
. dump = snapshot_dump ,
. start = snapshot_start ,
. stop = snapshot_stop ,
. active_state = snapshot_active_state ,
. sub_state_to_string = snapshot_sub_state_to_string ,
2010-01-23 03:52:57 +03:00
2010-04-18 05:07:42 +04:00
. bus_message_handler = bus_snapshot_message_handler
2010-01-23 03:52:57 +03:00
} ;