2005-01-31 07:28:44 +03:00
/*
* volume_id - reads filesystem label and uuid
*
* Copyright ( C ) 2004 Kay Sievers < kay . sievers @ vrfy . org >
*
2005-09-27 18:27:35 +04:00
* This program 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 version 2 of the License .
2005-01-31 07:28:44 +03:00
*/
# ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
# endif
# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
# include <errno.h>
# include <ctype.h>
2006-03-23 12:50:55 +03:00
# include "libvolume_id.h"
2005-02-23 04:58:31 +03:00
# include "util.h"
2005-01-31 07:28:44 +03:00
2006-08-20 20:23:48 +04:00
struct swap_header_v1_2 {
2005-08-01 03:33:36 +04:00
uint8_t bootbits [ 1024 ] ;
uint32_t version ;
uint32_t last_page ;
uint32_t nr_badpages ;
uint8_t uuid [ 16 ] ;
uint8_t volume_name [ 16 ] ;
2006-08-20 20:23:48 +04:00
} PACKED ;
2005-02-09 03:02:18 +03:00
2005-01-31 07:28:44 +03:00
# define LARGEST_PAGESIZE 0x4000
2006-07-25 16:59:50 +04:00
int volume_id_probe_linux_swap ( struct volume_id * id , uint64_t off , uint64_t size )
2005-01-31 07:28:44 +03:00
{
2005-08-01 03:33:36 +04:00
const uint8_t * buf ;
2005-01-31 07:28:44 +03:00
unsigned int page ;
2006-08-20 20:23:48 +04:00
struct swap_header_v1_2 * sw ;
2005-01-31 07:28:44 +03:00
2006-04-08 07:04:35 +04:00
info ( " probing at offset 0x%llx " , ( unsigned long long ) off ) ;
2005-02-09 03:02:18 +03:00
2006-08-20 20:23:48 +04:00
/* eek, the swap signature is at the end of the PAGE_SIZE */
2005-01-31 07:28:44 +03:00
for ( page = 0x1000 ; page < = LARGEST_PAGESIZE ; page < < = 1 ) {
buf = volume_id_get_buffer ( id , off + page - 10 , 10 ) ;
if ( buf = = NULL )
return - 1 ;
2005-02-05 06:10:48 +03:00
if ( memcmp ( buf , " SWAP-SPACE " , 10 ) = = 0 ) {
2005-01-31 07:28:44 +03:00
strcpy ( id - > type_version , " 1 " ) ;
goto found ;
}
2005-02-05 06:10:48 +03:00
if ( memcmp ( buf , " SWAPSPACE2 " , 10 ) = = 0 ) {
2006-08-20 20:23:48 +04:00
id - > type = " swap " ;
2005-01-31 07:28:44 +03:00
strcpy ( id - > type_version , " 2 " ) ;
2006-08-20 20:23:48 +04:00
goto found_label ;
}
if ( memcmp ( buf , " S1SUSPEND " , 9 ) = = 0 ) {
id - > type = " suspend " ;
strcpy ( id - > type_version , " s1suspend " ) ;
goto found_label ;
}
if ( memcmp ( buf , " ULSUSPEND " , 9 ) = = 0 ) {
id - > type = " suspend " ;
strcpy ( id - > type_version , " ulsuspend " ) ;
goto found_label ;
2005-01-31 07:28:44 +03:00
}
}
return - 1 ;
2006-08-20 20:23:48 +04:00
found_label :
sw = ( struct swap_header_v1_2 * ) volume_id_get_buffer ( id , off , sizeof ( struct swap_header_v1_2 ) ) ;
if ( sw ! = NULL ) {
volume_id_set_label_raw ( id , sw - > volume_name , 16 ) ;
volume_id_set_label_string ( id , sw - > volume_name , 16 ) ;
2007-05-04 18:53:19 +04:00
volume_id_set_uuid ( id , sw - > uuid , 0 , UUID_DCE ) ;
2006-08-20 20:23:48 +04:00
}
2005-01-31 07:28:44 +03:00
found :
volume_id_set_usage ( id , VOLUME_ID_OTHER ) ;
return 0 ;
}