2001-11-21 15:47:42 +03:00
/*
2004-03-30 23:08:57 +04:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
* Copyright ( C ) 2004 Red Hat , Inc . All rights reserved .
2001-11-21 15:47:42 +03:00
*
2004-03-30 23:08:57 +04:00
* This file is part of the device - mapper userspace tools .
*
* 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
2001-11-21 15:47:42 +03:00
*/
2001-11-21 18:15:37 +03:00
# include "libdevmapper.h"
2004-02-24 21:50:09 +03:00
# include "log.h"
2001-11-21 15:47:42 +03:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
2003-11-13 16:14:28 +03:00
# include <dirent.h>
# include <errno.h>
2003-11-12 20:30:32 +03:00
# include <unistd.h>
# ifdef HAVE_GETOPTLONG
# include <getopt.h>
# define GETOPTLONG_FN(a, b, c, d, e) getopt_long((a), (b), (c), (d), (e))
# define OPTIND_INIT 0
# else
struct option {
} ;
extern int optind ;
extern char * optarg ;
# define GETOPTLONG_FN(a, b, c, d, e) getopt((a), (b), (c))
# define OPTIND_INIT 1
# endif
# ifdef linux
2004-07-01 19:14:29 +04:00
# include "kdev_t.h"
2003-11-12 20:30:32 +03:00
# else
# define MAJOR(x) major((x))
# define MINOR(x) minor((x))
# define MKDEV(x,y) makedev((x),(y))
# endif
2001-11-21 15:47:42 +03:00
# define LINE_SIZE 1024
# define err(msg, x...) fprintf(stderr, msg "\n", ##x)
2002-01-03 13:39:21 +03:00
/*
* We have only very simple switches ATM .
*/
enum {
READ_ONLY = 0 ,
2004-06-16 20:44:12 +04:00
COLS_ARG ,
2003-04-04 17:22:58 +04:00
MAJOR_ARG ,
2002-01-11 15:12:46 +03:00
MINOR_ARG ,
2003-11-12 20:30:32 +03:00
NOTABLE_ARG ,
UUID_ARG ,
2003-01-22 00:25:51 +03:00
VERBOSE_ARG ,
2003-07-04 23:38:49 +04:00
VERSION_ARG ,
2002-01-03 13:39:21 +03:00
NUM_SWITCHES
} ;
static int _switches [ NUM_SWITCHES ] ;
2002-01-11 15:12:46 +03:00
static int _values [ NUM_SWITCHES ] ;
2003-11-12 20:30:32 +03:00
static char * _uuid ;
2002-01-03 13:39:21 +03:00
/*
* Commands
*/
2001-11-21 15:47:42 +03:00
static int _parse_file ( struct dm_task * dmt , const char * file )
{
2004-03-19 18:52:22 +03:00
char buffer [ LINE_SIZE ] , ttype [ LINE_SIZE ] , * ptr , * comment ;
2003-11-12 20:30:32 +03:00
FILE * fp ;
2002-03-07 23:56:10 +03:00
unsigned long long start , size ;
int r = 0 , n , line = 0 ;
2001-11-21 15:47:42 +03:00
2003-11-12 20:30:32 +03:00
/* OK for empty stdin */
if ( file ) {
if ( ! ( fp = fopen ( file , " r " ) ) ) {
err ( " Couldn't open '%s' for reading " , file ) ;
return 0 ;
}
} else
fp = stdin ;
2001-11-21 15:47:42 +03:00
2002-03-07 23:56:10 +03:00
while ( fgets ( buffer , sizeof ( buffer ) , fp ) ) {
2001-11-21 15:47:42 +03:00
line + + ;
/* trim trailing space */
for ( ptr = buffer + strlen ( buffer ) - 1 ; ptr > = buffer ; ptr - - )
if ( ! isspace ( ( int ) * ptr ) )
break ;
ptr + + ;
* ptr = ' \0 ' ;
/* trim leading space */
2002-03-07 23:56:10 +03:00
for ( ptr = buffer ; * ptr & & isspace ( ( int ) * ptr ) ; ptr + + ) ;
2001-11-21 15:47:42 +03:00
2002-03-07 23:56:10 +03:00
if ( ! * ptr | | * ptr = = ' # ' )
continue ;
2001-11-21 15:47:42 +03:00
2004-03-19 18:52:22 +03:00
if ( sscanf ( ptr , " %llu %llu %s %n " ,
& start , & size , ttype , & n ) < 3 ) {
2002-03-07 23:56:10 +03:00
err ( " %s:%d Invalid format " , file , line ) ;
goto out ;
}
2001-11-21 15:47:42 +03:00
ptr + = n ;
if ( ( comment = strchr ( ptr , ( int ) ' # ' ) ) )
* comment = ' \0 ' ;
2002-03-07 23:56:10 +03:00
if ( ! dm_task_add_target ( dmt , start , size , ttype , ptr ) )
goto out ;
}
r = 1 ;
2001-11-21 15:47:42 +03:00
2002-03-07 23:56:10 +03:00
out :
2003-11-12 20:30:32 +03:00
if ( file )
fclose ( fp ) ;
2002-03-07 23:56:10 +03:00
return r ;
2001-11-21 15:47:42 +03:00
}
2004-06-16 20:44:12 +04:00
static void _display_info_cols ( struct dm_task * dmt , struct dm_info * info )
2003-07-02 01:20:58 +04:00
{
2004-06-16 20:44:12 +04:00
static int _headings = 0 ;
2003-07-02 01:20:58 +04:00
const char * uuid ;
2004-06-16 20:44:12 +04:00
if ( ! info - > exists ) {
printf ( " Device does not exist. \n " ) ;
2003-07-02 01:20:58 +04:00
return ;
2004-06-16 20:44:12 +04:00
}
2003-07-02 01:20:58 +04:00
2004-06-16 20:44:12 +04:00
if ( ! _headings ) {
printf ( " Name Maj Min Stat Open Targ Event UUID \n " ) ;
_headings = 1 ;
}
printf ( " %-16s " , dm_task_get_name ( dmt ) ) ;
printf ( " %3d %3d %s%s%s%s %4d %4d %6 " PRIu32 " " ,
info - > major , info - > minor ,
info - > live_table ? " L " : " - " ,
info - > inactive_table ? " I " : " - " ,
info - > suspended ? " s " : " - " ,
info - > read_only ? " r " : " w " ,
info - > open_count , info - > target_count , info - > event_nr ) ;
if ( ( uuid = dm_task_get_uuid ( dmt ) ) & & * uuid )
printf ( " %s " , uuid ) ;
printf ( " \n " ) ;
}
static void _display_info_long ( struct dm_task * dmt , struct dm_info * info )
{
const char * uuid ;
if ( ! info - > exists ) {
2003-07-02 01:20:58 +04:00
printf ( " Device does not exist. \n " ) ;
return ;
}
printf ( " Name: %s \n " , dm_task_get_name ( dmt ) ) ;
printf ( " State: %s%s \n " ,
2004-06-16 20:44:12 +04:00
info - > suspended ? " SUSPENDED " : " ACTIVE " ,
info - > read_only ? " (READ-ONLY) " : " " ) ;
2003-07-02 01:20:58 +04:00
2004-06-16 20:44:12 +04:00
if ( ! info - > live_table & & ! info - > inactive_table )
2003-07-02 01:20:58 +04:00
printf ( " Tables present: None \n " ) ;
else
printf ( " Tables present: %s%s%s \n " ,
2004-06-16 20:44:12 +04:00
info - > live_table ? " LIVE " : " " ,
info - > live_table & & info - > inactive_table ? " & " : " " ,
info - > inactive_table ? " INACTIVE " : " " ) ;
2003-07-02 01:20:58 +04:00
2004-06-16 20:44:12 +04:00
if ( info - > open_count ! = - 1 )
printf ( " Open count: %d \n " , info - > open_count ) ;
2003-07-02 01:20:58 +04:00
2004-06-16 20:44:12 +04:00
printf ( " Event number: % " PRIu32 " \n " , info - > event_nr ) ;
printf ( " Major, minor: %d, %d \n " , info - > major , info - > minor ) ;
2003-07-02 01:20:58 +04:00
2004-06-16 20:44:12 +04:00
if ( info - > target_count ! = - 1 )
printf ( " Number of targets: %d \n " , info - > target_count ) ;
2003-07-02 01:20:58 +04:00
if ( ( uuid = dm_task_get_uuid ( dmt ) ) & & * uuid )
printf ( " UUID: %s \n " , uuid ) ;
2003-07-04 23:38:49 +04:00
printf ( " \n " ) ;
2003-07-02 01:20:58 +04:00
}
2004-06-16 20:44:12 +04:00
static void _display_info ( struct dm_task * dmt )
{
struct dm_info info ;
if ( ! dm_task_get_info ( dmt , & info ) )
return ;
if ( _switches [ COLS_ARG ] )
_display_info_cols ( dmt , & info ) ;
else
_display_info_long ( dmt , & info ) ;
}
2002-03-12 01:44:36 +03:00
static int _load ( int task , const char * name , const char * file , const char * uuid )
2001-11-21 15:47:42 +03:00
{
int r = 0 ;
struct dm_task * dmt ;
if ( ! ( dmt = dm_task_create ( task ) ) )
return 0 ;
if ( ! dm_task_set_name ( dmt , name ) )
goto out ;
2002-03-12 01:44:36 +03:00
if ( uuid & & ! dm_task_set_uuid ( dmt , uuid ) )
goto out ;
2003-11-12 20:30:32 +03:00
if ( ! _switches [ NOTABLE_ARG ] & & ! _parse_file ( dmt , file ) )
2001-11-21 15:47:42 +03:00
goto out ;
2003-11-13 16:14:28 +03:00
2002-01-03 13:39:21 +03:00
if ( _switches [ READ_ONLY ] & & ! dm_task_set_ro ( dmt ) )
goto out ;
2003-04-04 17:22:58 +04:00
if ( _switches [ MAJOR_ARG ] & & ! dm_task_set_major ( dmt , _values [ MAJOR_ARG ] ) )
goto out ;
2002-01-11 15:12:46 +03:00
if ( _switches [ MINOR_ARG ] & & ! dm_task_set_minor ( dmt , _values [ MINOR_ARG ] ) )
goto out ;
2001-11-21 15:47:42 +03:00
if ( ! dm_task_run ( dmt ) )
goto out ;
r = 1 ;
2003-07-04 23:38:49 +04:00
if ( _switches [ VERBOSE_ARG ] )
_display_info ( dmt ) ;
2003-07-02 01:20:58 +04:00
2002-03-07 23:56:10 +03:00
out :
2001-11-21 15:47:42 +03:00
dm_task_destroy ( dmt ) ;
return r ;
}
2003-09-16 18:13:51 +04:00
static int _create ( int argc , char * * argv , void * data )
2001-11-21 15:47:42 +03:00
{
2003-11-12 20:30:32 +03:00
return _load ( DM_DEVICE_CREATE , argv [ 1 ] , ( argc = = 3 ) ? argv [ 2 ] : NULL ,
_switches [ UUID_ARG ] ? _uuid : NULL ) ;
2001-11-21 15:47:42 +03:00
}
2003-09-16 18:13:51 +04:00
static int _reload ( int argc , char * * argv , void * data )
2001-11-21 15:47:42 +03:00
{
2003-11-12 20:30:32 +03:00
if ( _switches [ NOTABLE_ARG ] ) {
err ( " --notable only available when creating new device \n " ) ;
return 0 ;
}
2003-11-13 16:14:28 +03:00
return _load ( DM_DEVICE_RELOAD , argv [ 1 ] ,
2003-11-12 20:30:32 +03:00
( argc = = 3 ) ? argv [ 2 ] : NULL , NULL ) ;
2001-11-21 15:47:42 +03:00
}
2003-09-16 18:13:51 +04:00
static int _rename ( int argc , char * * argv , void * data )
2002-01-11 15:12:46 +03:00
{
int r = 0 ;
struct dm_task * dmt ;
2002-03-07 23:56:10 +03:00
if ( ! ( dmt = dm_task_create ( DM_DEVICE_RENAME ) ) )
return 0 ;
2002-01-11 15:12:46 +03:00
2002-03-07 23:56:10 +03:00
if ( ! dm_task_set_name ( dmt , argv [ 1 ] ) )
goto out ;
2002-01-11 15:12:46 +03:00
if ( ! dm_task_set_newname ( dmt , argv [ 2 ] ) )
goto out ;
2002-03-07 23:56:10 +03:00
if ( ! dm_task_run ( dmt ) )
goto out ;
2002-01-11 15:12:46 +03:00
2002-03-07 23:56:10 +03:00
r = 1 ;
2002-01-11 15:12:46 +03:00
2002-03-07 23:56:10 +03:00
out :
dm_task_destroy ( dmt ) ;
2002-01-11 15:12:46 +03:00
2002-03-07 23:56:10 +03:00
return r ;
2002-01-11 15:12:46 +03:00
}
2001-11-21 15:47:42 +03:00
2004-06-09 00:34:40 +04:00
static int _message ( int argc , char * * argv , void * data )
{
int r = 0 , sz = 1 , i ;
struct dm_task * dmt ;
char * str ;
if ( ! ( dmt = dm_task_create ( DM_DEVICE_TARGET_MSG ) ) )
return 0 ;
if ( ! dm_task_set_name ( dmt , argv [ 1 ] ) )
goto out ;
if ( ! dm_task_set_sector ( dmt , atoll ( argv [ 2 ] ) ) )
goto out ;
argc - = 3 ;
argv + = 3 ;
for ( i = 0 ; i < argc ; i + + )
sz + = strlen ( argv [ i ] ) + 1 ;
str = malloc ( sz ) ;
2004-06-10 20:14:16 +04:00
memset ( str , 0 , sz ) ;
2004-06-09 00:34:40 +04:00
for ( i = 0 ; i < argc ; i + + ) {
if ( i )
strcat ( str , " " ) ;
strcat ( str , argv [ i ] ) ;
}
if ( ! dm_task_set_message ( dmt , str ) )
goto out ;
free ( str ) ;
if ( ! dm_task_run ( dmt ) )
goto out ;
r = 1 ;
out :
dm_task_destroy ( dmt ) ;
return r ;
}
2003-09-16 18:13:51 +04:00
static int _version ( int argc , char * * argv , void * data )
2002-01-15 18:21:57 +03:00
{
int r = 0 ;
struct dm_task * dmt ;
2002-01-17 16:19:55 +03:00
char version [ 80 ] ;
2002-01-15 18:21:57 +03:00
2002-01-17 17:13:25 +03:00
if ( dm_get_library_version ( version , sizeof ( version ) ) )
printf ( " Library version: %s \n " , version ) ;
2002-01-15 18:21:57 +03:00
if ( ! ( dmt = dm_task_create ( DM_DEVICE_VERSION ) ) )
return 0 ;
if ( ! dm_task_run ( dmt ) )
goto out ;
2002-03-07 23:56:10 +03:00
if ( ! dm_task_get_driver_version ( dmt , ( char * ) & version ,
2004-06-09 00:34:40 +04:00
sizeof ( version ) ) ) {
2002-01-15 18:21:57 +03:00
goto out ;
2004-06-09 00:34:40 +04:00
}
2002-01-15 18:21:57 +03:00
printf ( " Driver version: %s \n " , version ) ;
r = 1 ;
out :
dm_task_destroy ( dmt ) ;
return r ;
}
2004-01-23 17:09:33 +03:00
static int _simple ( int task , const char * name , uint32_t event_nr , int display )
2001-11-21 15:47:42 +03:00
{
int r = 0 ;
/* remove <dev_name> */
struct dm_task * dmt ;
if ( ! ( dmt = dm_task_create ( task ) ) )
return 0 ;
if ( ! dm_task_set_name ( dmt , name ) )
goto out ;
2004-01-23 17:09:33 +03:00
if ( event_nr & & ! dm_task_set_event_nr ( dmt , event_nr ) )
goto out ;
2001-11-21 15:47:42 +03:00
r = dm_task_run ( dmt ) ;
2003-07-04 23:38:49 +04:00
if ( r & & display & & _switches [ VERBOSE_ARG ] )
2003-07-02 01:20:58 +04:00
_display_info ( dmt ) ;
2002-03-07 23:56:10 +03:00
out :
2001-11-21 15:47:42 +03:00
dm_task_destroy ( dmt ) ;
return r ;
}
2003-09-16 18:13:51 +04:00
static int _remove_all ( int argc , char * * argv , void * data )
2002-03-07 23:56:10 +03:00
{
2004-01-23 17:09:33 +03:00
return _simple ( DM_DEVICE_REMOVE_ALL , " " , 0 , 0 ) ;
2002-03-07 23:56:10 +03:00
}
2003-09-16 18:13:51 +04:00
static int _remove ( int argc , char * * argv , void * data )
2001-11-21 15:47:42 +03:00
{
2004-01-23 17:09:33 +03:00
return _simple ( DM_DEVICE_REMOVE , argv [ 1 ] , 0 , 0 ) ;
2001-11-21 15:47:42 +03:00
}
2003-09-16 18:13:51 +04:00
static int _suspend ( int argc , char * * argv , void * data )
2001-11-21 15:47:42 +03:00
{
2004-01-23 17:09:33 +03:00
return _simple ( DM_DEVICE_SUSPEND , argv [ 1 ] , 0 , 1 ) ;
2001-11-21 15:47:42 +03:00
}
2003-09-16 18:13:51 +04:00
static int _resume ( int argc , char * * argv , void * data )
2001-11-21 15:47:42 +03:00
{
2004-01-23 17:09:33 +03:00
return _simple ( DM_DEVICE_RESUME , argv [ 1 ] , 0 , 1 ) ;
2003-07-02 01:20:58 +04:00
}
2003-09-16 18:13:51 +04:00
static int _clear ( int argc , char * * argv , void * data )
2003-07-02 01:20:58 +04:00
{
2004-01-23 17:09:33 +03:00
return _simple ( DM_DEVICE_CLEAR , argv [ 1 ] , 0 , 1 ) ;
2001-11-21 15:47:42 +03:00
}
2003-09-16 18:13:51 +04:00
static int _wait ( int argc , char * * argv , void * data )
2002-05-03 15:55:58 +04:00
{
2004-01-23 17:09:33 +03:00
return _simple ( DM_DEVICE_WAITEVENT , argv [ 1 ] ,
( argc = = 3 ) ? atoi ( argv [ 2 ] ) : 0 , 1 ) ;
2002-05-03 15:55:58 +04:00
}
2003-09-16 18:13:51 +04:00
static int _process_all ( int argc , char * * argv ,
2003-11-13 16:14:28 +03:00
int ( * fn ) ( int argc , char * * argv , void * data ) )
2003-09-16 18:13:51 +04:00
{
2003-11-13 16:14:28 +03:00
int r = 1 ;
2003-09-16 18:13:51 +04:00
struct dm_names * names ;
unsigned next = 0 ;
struct dm_task * dmt ;
if ( ! ( dmt = dm_task_create ( DM_DEVICE_LIST ) ) )
return 0 ;
2003-11-13 16:14:28 +03:00
if ( ! dm_task_run ( dmt ) ) {
r = 0 ;
2003-09-16 18:13:51 +04:00
goto out ;
2003-11-13 16:14:28 +03:00
}
2003-09-16 18:13:51 +04:00
2003-11-13 16:14:28 +03:00
if ( ! ( names = dm_task_get_names ( dmt ) ) ) {
r = 0 ;
2003-09-16 18:13:51 +04:00
goto out ;
2003-11-13 16:14:28 +03:00
}
2003-09-16 18:13:51 +04:00
if ( ! names - > dev ) {
printf ( " No devices found \n " ) ;
goto out ;
}
do {
names = ( void * ) names + next ;
2003-11-13 16:14:28 +03:00
if ( ! fn ( argc , argv , ( void * ) names ) )
2003-09-16 18:13:51 +04:00
r = 0 ;
next = names - > next ;
} while ( next ) ;
out :
dm_task_destroy ( dmt ) ;
return r ;
}
static int _status ( int argc , char * * argv , void * data )
2002-05-03 15:55:58 +04:00
{
int r = 0 ;
struct dm_task * dmt ;
void * next = NULL ;
2002-05-10 19:25:38 +04:00
uint64_t start , length ;
2002-05-03 15:55:58 +04:00
char * target_type = NULL ;
char * params ;
int cmd ;
2003-11-13 16:14:28 +03:00
struct dm_names * names = ( struct dm_names * ) data ;
2003-09-16 18:13:51 +04:00
char * name ;
if ( argc = = 1 & & ! data )
return _process_all ( argc , argv , _status ) ;
if ( data )
name = names - > name ;
else
name = argv [ 1 ] ;
2002-05-03 15:55:58 +04:00
2003-11-13 16:14:28 +03:00
if ( ! strcmp ( argv [ 0 ] , " table " ) )
2002-05-10 19:25:38 +04:00
cmd = DM_DEVICE_TABLE ;
2003-11-13 16:14:28 +03:00
else
cmd = DM_DEVICE_STATUS ;
2002-05-03 15:55:58 +04:00
if ( ! ( dmt = dm_task_create ( cmd ) ) )
return 0 ;
2003-09-16 18:13:51 +04:00
if ( ! dm_task_set_name ( dmt , name ) )
2002-05-03 15:55:58 +04:00
goto out ;
if ( ! dm_task_run ( dmt ) )
goto out ;
2003-07-04 23:38:49 +04:00
if ( _switches [ VERBOSE_ARG ] )
2003-07-02 01:20:58 +04:00
_display_info ( dmt ) ;
2002-05-03 15:55:58 +04:00
/* Fetch targets and print 'em */
do {
2002-05-10 19:25:38 +04:00
next = dm_get_next_target ( dmt , next , & start , & length ,
& target_type , & params ) ;
2003-09-16 18:13:51 +04:00
if ( data & & ! _switches [ VERBOSE_ARG ] )
printf ( " %s: " , name ) ;
2002-05-10 19:25:38 +04:00
if ( target_type ) {
2003-04-04 17:22:58 +04:00
printf ( " % " PRIu64 " % " PRIu64 " %s %s \n " ,
2002-05-10 19:25:38 +04:00
start , length , target_type , params ) ;
}
2002-05-03 15:55:58 +04:00
} while ( next ) ;
2003-09-16 18:13:51 +04:00
if ( data & & _switches [ VERBOSE_ARG ] )
printf ( " \n " ) ;
2002-05-03 15:55:58 +04:00
r = 1 ;
out :
dm_task_destroy ( dmt ) ;
return r ;
}
2004-01-23 17:37:47 +03:00
/* Show target names and their version numbers */
static int _targets ( int argc , char * * argv , void * data )
{
int r = 0 ;
struct dm_task * dmt ;
struct dm_versions * target ;
struct dm_versions * last_target ;
if ( ! ( dmt = dm_task_create ( DM_DEVICE_LIST_VERSIONS ) ) )
return 0 ;
if ( ! dm_task_run ( dmt ) )
goto out ;
target = dm_task_get_versions ( dmt ) ;
/* Fetch targets and print 'em */
do {
last_target = target ;
printf ( " %-16s v%d.%d.%d \n " , target - > name , target - > version [ 0 ] ,
target - > version [ 1 ] , target - > version [ 2 ] ) ;
target = ( void * ) target + target - > next ;
} while ( last_target ! = target ) ;
r = 1 ;
out :
dm_task_destroy ( dmt ) ;
return r ;
}
2004-03-30 18:31:58 +04:00
static int _mknodes ( int argc , char * * argv , void * data )
{
struct dm_task * dmt ;
int r = 0 ;
if ( ! ( dmt = dm_task_create ( DM_DEVICE_MKNODES ) ) )
return 0 ;
if ( argc = = 2 & & ! dm_task_set_name ( dmt , argv [ 1 ] ) )
goto out ;
if ( ! dm_task_run ( dmt ) )
goto out ;
r = 1 ;
out :
dm_task_destroy ( dmt ) ;
return r ;
}
2003-09-16 18:13:51 +04:00
static int _info ( int argc , char * * argv , void * data )
2001-11-21 15:47:42 +03:00
{
int r = 0 ;
struct dm_task * dmt ;
2003-11-13 16:14:28 +03:00
struct dm_names * names = ( struct dm_names * ) data ;
2004-03-30 18:31:58 +04:00
char * name = NULL ;
2003-09-16 18:13:51 +04:00
if ( argc = = 1 & & ! data )
return _process_all ( argc , argv , _info ) ;
if ( data )
name = names - > name ;
else
name = argv [ 1 ] ;
2001-11-21 15:47:42 +03:00
2004-03-30 18:31:58 +04:00
if ( ! ( dmt = dm_task_create ( DM_DEVICE_INFO ) ) )
2001-11-21 15:47:42 +03:00
return 0 ;
2004-03-30 18:31:58 +04:00
if ( name & & ! dm_task_set_name ( dmt , name ) )
2001-11-21 15:47:42 +03:00
goto out ;
if ( ! dm_task_run ( dmt ) )
goto out ;
2004-03-30 18:31:58 +04:00
_display_info ( dmt ) ;
2003-09-16 18:13:51 +04:00
2001-11-21 15:47:42 +03:00
r = 1 ;
2002-03-07 23:56:10 +03:00
out :
2001-11-21 15:47:42 +03:00
dm_task_destroy ( dmt ) ;
return r ;
}
2003-09-16 18:13:51 +04:00
static int _deps ( int argc , char * * argv , void * data )
2002-03-06 17:38:25 +03:00
{
2003-03-28 21:58:59 +03:00
int r = 0 ;
uint32_t i ;
2002-03-06 17:38:25 +03:00
struct dm_deps * deps ;
struct dm_task * dmt ;
struct dm_info info ;
2003-11-13 16:14:28 +03:00
struct dm_names * names = ( struct dm_names * ) data ;
2003-09-16 18:13:51 +04:00
char * name ;
if ( argc = = 1 & & ! data )
return _process_all ( argc , argv , _deps ) ;
if ( data )
name = names - > name ;
else
name = argv [ 1 ] ;
2002-03-06 17:38:25 +03:00
if ( ! ( dmt = dm_task_create ( DM_DEVICE_DEPS ) ) )
return 0 ;
2003-09-16 18:13:51 +04:00
if ( ! dm_task_set_name ( dmt , name ) )
2002-03-06 17:38:25 +03:00
goto out ;
if ( ! dm_task_run ( dmt ) )
goto out ;
2002-03-06 22:42:23 +03:00
if ( ! dm_task_get_info ( dmt , & info ) )
goto out ;
2002-03-06 17:38:25 +03:00
if ( ! ( deps = dm_task_get_deps ( dmt ) ) )
goto out ;
if ( ! info . exists ) {
printf ( " Device does not exist. \n " ) ;
r = 1 ;
goto out ;
}
2003-07-04 23:38:49 +04:00
if ( _switches [ VERBOSE_ARG ] )
_display_info ( dmt ) ;
2003-07-02 01:20:58 +04:00
2003-09-16 18:13:51 +04:00
if ( data & & ! _switches [ VERBOSE_ARG ] )
printf ( " %s: " , name ) ;
2002-03-06 17:38:25 +03:00
printf ( " %d dependencies \t : " , deps - > count ) ;
for ( i = 0 ; i < deps - > count ; i + + )
printf ( " (%d, %d) " ,
( int ) MAJOR ( deps - > device [ i ] ) ,
( int ) MINOR ( deps - > device [ i ] ) ) ;
printf ( " \n " ) ;
2003-09-16 18:13:51 +04:00
if ( data & & _switches [ VERBOSE_ARG ] )
printf ( " \n " ) ;
2002-03-06 17:38:25 +03:00
r = 1 ;
2002-03-07 23:56:10 +03:00
out :
2002-03-06 17:38:25 +03:00
dm_task_destroy ( dmt ) ;
return r ;
}
2003-09-16 18:13:51 +04:00
static int _display_name ( int argc , char * * argv , void * data )
2003-07-02 01:20:58 +04:00
{
2003-11-13 16:14:28 +03:00
struct dm_names * names = ( struct dm_names * ) data ;
2003-07-02 01:20:58 +04:00
2003-09-16 18:13:51 +04:00
printf ( " %s \t (%d, %d) \n " , names - > name ,
( int ) MAJOR ( names - > dev ) , ( int ) MINOR ( names - > dev ) ) ;
2003-07-02 01:20:58 +04:00
2003-09-16 18:13:51 +04:00
return 1 ;
}
2003-07-02 01:20:58 +04:00
2003-09-16 18:13:51 +04:00
static int _ls ( int argc , char * * argv , void * data )
{
return _process_all ( argc , argv , _display_name ) ;
2003-07-02 01:20:58 +04:00
}
2001-11-21 15:47:42 +03:00
/*
* dispatch table
*/
2003-09-16 18:13:51 +04:00
typedef int ( * command_fn ) ( int argc , char * * argv , void * data ) ;
2001-11-21 15:47:42 +03:00
struct command {
2003-01-22 00:25:51 +03:00
const char * name ;
const char * help ;
2002-03-12 01:44:36 +03:00
int min_args ;
int max_args ;
2001-11-21 15:47:42 +03:00
command_fn fn ;
} ;
static struct command _commands [ ] = {
2003-11-12 20:30:32 +03:00
{ " create " , " <dev_name> [-u <uuid>] [--notable] [<table_file>] " ,
1 , 2 , _create } ,
2002-03-12 01:44:36 +03:00
{ " remove " , " <dev_name> " , 1 , 1 , _remove } ,
{ " remove_all " , " " , 0 , 0 , _remove_all } ,
{ " suspend " , " <dev_name> " , 1 , 1 , _suspend } ,
{ " resume " , " <dev_name> " , 1 , 1 , _resume } ,
2003-11-12 20:30:32 +03:00
{ " load " , " <dev_name> [<table_file>] " , 1 , 2 , _reload } ,
2003-07-02 01:20:58 +04:00
{ " clear " , " <dev_name> " , 1 , 1 , _clear } ,
2003-11-12 20:30:32 +03:00
{ " reload " , " <dev_name> [<table_file>] " , 1 , 2 , _reload } ,
2003-07-02 01:20:58 +04:00
{ " rename " , " <dev_name> <new_name> " , 2 , 2 , _rename } ,
2004-06-09 00:34:40 +04:00
{ " message " , " <dev_name> <sector> <message> " , 3 , - 1 , _message } ,
2003-07-02 01:20:58 +04:00
{ " ls " , " " , 0 , 0 , _ls } ,
2003-09-16 18:13:51 +04:00
{ " info " , " [<dev_name>] " , 0 , 1 , _info } ,
{ " deps " , " [<dev_name>] " , 0 , 1 , _deps } ,
{ " status " , " [<dev_name>] " , 0 , 1 , _status } ,
{ " table " , " [<dev_name>] " , 0 , 1 , _status } ,
2004-01-23 17:09:33 +03:00
{ " wait " , " <dev_name> [<event_nr>] " , 1 , 2 , _wait } ,
2004-03-30 18:31:58 +04:00
{ " mknodes " , " [<dev_name>] " , 0 , 1 , _mknodes } ,
2004-01-23 17:37:47 +03:00
{ " targets " , " " , 0 , 0 , _targets } ,
2002-03-12 01:44:36 +03:00
{ " version " , " " , 0 , 0 , _version } ,
{ NULL , NULL , 0 , 0 , NULL }
2001-11-21 15:47:42 +03:00
} ;
2003-04-04 17:22:58 +04:00
static void _usage ( FILE * out )
2001-11-21 15:47:42 +03:00
{
int i ;
2003-07-04 23:38:49 +04:00
fprintf ( out , " Usage: \n \n " ) ;
fprintf ( out , " dmsetup [--version] [-v|--verbose [-v|--verbose ...]] \n "
2003-11-13 16:14:28 +03:00
" [-r|--readonly] [-j|--major <major>] "
" [-m|--minor <minor>] \n \n " ) ;
2001-11-21 15:47:42 +03:00
for ( i = 0 ; _commands [ i ] . name ; i + + )
2002-03-07 23:56:10 +03:00
fprintf ( out , " \t %s %s \n " , _commands [ i ] . name , _commands [ i ] . help ) ;
2001-11-21 15:47:42 +03:00
return ;
}
2002-01-03 13:39:21 +03:00
static struct command * _find_command ( const char * name )
2001-11-21 15:47:42 +03:00
{
int i ;
for ( i = 0 ; _commands [ i ] . name ; i + + )
if ( ! strcmp ( _commands [ i ] . name , name ) )
return _commands + i ;
return NULL ;
}
2002-01-03 13:39:21 +03:00
static int _process_switches ( int * argc , char * * * argv )
{
2003-01-22 00:25:51 +03:00
int ind ;
2002-10-09 00:16:44 +04:00
int c ;
2002-01-03 13:39:21 +03:00
2003-11-12 20:30:32 +03:00
# ifdef HAVE_GETOPTLONG
2002-01-03 13:39:21 +03:00
static struct option long_options [ ] = {
2004-06-16 20:44:12 +04:00
{ " columns " , 0 , NULL , COLS_ARG } ,
2003-07-04 23:38:49 +04:00
{ " readonly " , 0 , NULL , READ_ONLY } ,
2003-04-04 17:22:58 +04:00
{ " major " , 1 , NULL , MAJOR_ARG } ,
2002-01-11 15:12:46 +03:00
{ " minor " , 1 , NULL , MINOR_ARG } ,
2003-11-12 20:30:32 +03:00
{ " notable " , 0 , NULL , NOTABLE_ARG } ,
{ " uuid " , 1 , NULL , UUID_ARG } ,
2003-01-22 00:25:51 +03:00
{ " verbose " , 1 , NULL , VERBOSE_ARG } ,
2003-07-04 23:38:49 +04:00
{ " version " , 0 , NULL , VERSION_ARG } ,
2002-01-11 15:12:46 +03:00
{ " " , 0 , NULL , 0 }
2002-01-03 13:39:21 +03:00
} ;
2003-11-12 20:30:32 +03:00
# else
struct option long_options ;
# endif
2002-01-03 13:39:21 +03:00
/*
* Zero all the index counts .
*/
memset ( & _switches , 0 , sizeof ( _switches ) ) ;
2002-01-11 15:12:46 +03:00
memset ( & _values , 0 , sizeof ( _values ) ) ;
2002-01-03 13:39:21 +03:00
2003-11-12 20:30:32 +03:00
optarg = 0 ;
optind = OPTIND_INIT ;
2004-06-16 20:44:12 +04:00
while ( ( c = GETOPTLONG_FN ( * argc , * argv , " cCj:m:nru:v " ,
2003-11-13 16:14:28 +03:00
long_options , & ind ) ) ! = - 1 ) {
2004-06-16 20:44:12 +04:00
if ( c = = ' c ' | | c = = ' C ' | | ind = = COLS_ARG )
_switches [ COLS_ARG ] + + ;
2003-01-22 00:25:51 +03:00
if ( c = = ' r ' | | ind = = READ_ONLY )
2002-01-03 13:39:21 +03:00
_switches [ READ_ONLY ] + + ;
2003-04-04 17:22:58 +04:00
if ( c = = ' j ' | | ind = = MAJOR_ARG ) {
_switches [ MAJOR_ARG ] + + ;
_values [ MAJOR_ARG ] = atoi ( optarg ) ;
}
2003-01-22 00:25:51 +03:00
if ( c = = ' m ' | | ind = = MINOR_ARG ) {
2002-01-11 15:12:46 +03:00
_switches [ MINOR_ARG ] + + ;
_values [ MINOR_ARG ] = atoi ( optarg ) ;
}
2003-11-12 20:30:32 +03:00
if ( c = = ' n ' | | ind = = NOTABLE_ARG )
_switches [ NOTABLE_ARG ] + + ;
2003-01-22 00:25:51 +03:00
if ( c = = ' v ' | | ind = = VERBOSE_ARG )
_switches [ VERBOSE_ARG ] + + ;
2003-11-12 20:30:32 +03:00
if ( c = = ' u ' | | ind = = UUID_ARG ) {
_switches [ UUID_ARG ] + + ;
_uuid = optarg ;
}
2003-07-04 23:38:49 +04:00
if ( ( ind = = VERSION_ARG ) )
_switches [ VERSION_ARG ] + + ;
2002-01-11 15:12:46 +03:00
}
2002-01-03 13:39:21 +03:00
2003-07-04 23:38:49 +04:00
if ( _switches [ VERBOSE_ARG ] > 1 )
dm_log_init_verbose ( _switches [ VERBOSE_ARG ] - 1 ) ;
2003-01-22 00:25:51 +03:00
2002-01-03 13:39:21 +03:00
* argv + = optind ;
* argc - = optind ;
return 1 ;
}
2001-11-21 15:47:42 +03:00
int main ( int argc , char * * argv )
{
struct command * c ;
2002-01-03 13:39:21 +03:00
if ( ! _process_switches ( & argc , & argv ) ) {
fprintf ( stderr , " Couldn't process command line switches. \n " ) ;
exit ( 1 ) ;
}
2003-07-04 23:38:49 +04:00
if ( _switches [ VERSION_ARG ] ) {
c = _find_command ( " version " ) ;
goto doit ;
}
2002-01-15 18:21:57 +03:00
if ( argc = = 0 ) {
2001-11-21 15:47:42 +03:00
_usage ( stderr ) ;
exit ( 1 ) ;
}
2002-01-03 13:39:21 +03:00
if ( ! ( c = _find_command ( argv [ 0 ] ) ) ) {
2001-11-21 15:47:42 +03:00
fprintf ( stderr , " Unknown command \n " ) ;
_usage ( stderr ) ;
exit ( 1 ) ;
}
2004-06-09 00:34:40 +04:00
if ( argc < c - > min_args + 1 | |
( c - > max_args > = 0 & & argc > c - > max_args + 1 ) ) {
2001-11-21 15:47:42 +03:00
fprintf ( stderr , " Incorrect number of arguments \n " ) ;
_usage ( stderr ) ;
exit ( 1 ) ;
}
2003-07-04 23:38:49 +04:00
doit :
2003-09-16 18:13:51 +04:00
if ( ! c - > fn ( argc , argv , NULL ) ) {
2001-12-14 16:30:04 +03:00
fprintf ( stderr , " Command failed \n " ) ;
2001-11-21 15:47:42 +03:00
exit ( 1 ) ;
}
2003-07-02 01:20:58 +04:00
dm_lib_release ( ) ;
dm_lib_exit ( ) ;
2001-11-21 15:47:42 +03:00
return 0 ;
}