~ubuntu-branches/ubuntu/trusty/gparted/trusty

« back to all changes in this revision

Viewing changes to src/GParted_Core.cc

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2010-10-30 11:08:59 UTC
  • mfrom: (6.3.15 upstream)
  • Revision ID: james.westby@ubuntu.com-20101030110859-2pgeh1y8p7z8tsb6
Tags: 0.7.0-1
New upstream release
Fix gparted crash at start with glibmm-ERROR
Closes: 601818
LP: #609477, #617885
Fix crash moving more than one logical partition right
Closes: 601817
Skip move/copy action because linux swap contains no data
LP: #401228
Fix several memory leaks and valgrind errors
Remove unnecessary null pointer checks
Fix partitions moved or copied are 1 MiB larger
Insert additional translator comments
Add initial support for btrfs

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include "../include/OperationResizeMove.h"
29
29
#include "../include/OperationLabelPartition.h"
30
30
 
 
31
#include "../include/btrfs.h"
31
32
#include "../include/ext2.h"
32
33
#include "../include/ext3.h"
33
34
#include "../include/ext4.h"
42
43
#include "../include/hfsplus.h"
43
44
#include "../include/reiser4.h"
44
45
#include "../include/ufs.h"
45
 
 
46
46
#include <set>
47
47
#include <cerrno>
48
48
#include <cstring>
63
63
        lp_disk = NULL ;
64
64
        lp_partition = NULL ;
65
65
        p_filesystem = NULL ;
66
 
        set_thread_status_message("") ;
 
66
        thread_status_message = "" ;
67
67
 
68
68
        ped_exception_set_handler( ped_exception_handler ) ; 
69
69
 
86
86
{
87
87
        FILESYSTEMS .clear() ;
88
88
        
 
89
        FS fs_notsupp;
 
90
 
 
91
        btrfs fs_btrfs;
 
92
        FILESYSTEMS .push_back( fs_btrfs .get_filesystem_support() ) ;
 
93
 
89
94
        ext2 fs_ext2;
90
95
        FILESYSTEMS .push_back( fs_ext2 .get_filesystem_support() ) ;
91
96
        
128
133
        xfs fs_xfs;
129
134
        FILESYSTEMS .push_back( fs_xfs .get_filesystem_support() ) ;
130
135
 
131
 
        FS *fs ;
132
 
        //btrfs  FIXME:  Add full support when on-disk-format stabilized
133
 
        fs = new( FS ) ;
134
 
        fs ->filesystem = GParted::FS_BTRFS ;
135
 
        FILESYSTEMS .push_back( * fs ) ;
136
 
 
137
136
        //lvm2 physical volume -- not a file system
138
 
        fs = new( FS ) ;
139
 
        fs ->filesystem = GParted::FS_LVM2 ;
140
 
        FILESYSTEMS .push_back( * fs ) ;
 
137
        fs_notsupp .filesystem = GParted::FS_LVM2 ;
 
138
        FILESYSTEMS .push_back( fs_notsupp ) ;
141
139
 
142
140
        //luks encryption-- not a file system
143
 
        fs = new( FS ) ;
144
 
        fs ->filesystem = GParted::FS_LUKS ;
145
 
        FILESYSTEMS .push_back( * fs ) ;
 
141
        fs_notsupp .filesystem = GParted::FS_LUKS ;
 
142
        FILESYSTEMS .push_back( fs_notsupp ) ;
146
143
 
147
144
        //unknown file system (default when no match is found)
148
 
        fs = new( FS ) ;
149
 
        fs ->filesystem = GParted::FS_UNKNOWN ;
150
 
        FILESYSTEMS .push_back( * fs ) ;
 
145
        fs_notsupp .filesystem = GParted::FS_UNKNOWN ;
 
146
        FILESYSTEMS .push_back( fs_notsupp ) ;
151
147
}
152
148
 
153
149
void GParted_Core::set_user_devices( const std::vector<Glib::ustring> & user_devices ) 
336
332
                        //harddisk without disklabel
337
333
                        else
338
334
                        {
339
 
                                temp_device .disktype = _("unrecognized") ;
 
335
                                temp_device .disktype =
 
336
                                                /* TO TRANSLATORS:  unrecognized
 
337
                                                 * means that the partition table for this
 
338
                                                 * disk device is unknown or not recognized.
 
339
                                                 */
 
340
                                                _("unrecognized") ;
340
341
                                temp_device .max_prims = -1 ;
341
342
                                
342
343
                                Partition partition_temp ;
526
527
        //do some basic checks on the partition
527
528
        if ( partition .get_sector_length() <= 0 )
528
529
        {
529
 
                error = String::ucompose( _("A partition cannot have a length of %1 sectors"),
 
530
                error = String::ucompose(
 
531
                                /* TO TRANSLATORS:  looks like   A partition cannot have a length of -1 sectors */
 
532
                                _("A partition cannot have a length of %1 sectors"),
530
533
                                partition .get_sector_length() ) ;
531
534
                return false ;
532
535
        }
534
537
        if ( partition .get_sector_length() < partition .sectors_used )
535
538
        {
536
539
                error = String::ucompose(
 
540
                                /* TO TRANSLATORS: looks like   A partition with used sectors (2048) greater than its length (1536) is not valid */
537
541
                                _("A partition with used sectors (%1) greater than its length (%2) is not valid"),
538
542
                                partition .sectors_used,
539
543
                                partition .get_sector_length() ) ;
857
861
        return paths ;
858
862
}
859
863
 
 
864
Glib::ustring GParted_Core::get_partition_path( PedPartition * lp_partition )
 
865
{
 
866
        DMRaid dmraid;   //Use cache of dmraid device information
 
867
        char * lp_path;  //we have to free the result of ped_partition_get_path()
 
868
        Glib::ustring partition_path;
 
869
 
 
870
        lp_path = ped_partition_get_path(lp_partition);
 
871
        partition_path = lp_path;
 
872
        free(lp_path);
 
873
 
 
874
        //Ensure partition path name is compatible with dmraid
 
875
        if (   dmraid .is_dmraid_supported()
 
876
            && dmraid .is_dmraid_device( partition_path )
 
877
           )
 
878
        {
 
879
                partition_path = dmraid .make_path_dmraid_compatible(partition_path);
 
880
        }
 
881
 
 
882
        return partition_path ;
 
883
}
 
884
 
860
885
void GParted_Core::set_device_partitions( Device & device ) 
861
886
{
862
887
        int EXT_INDEX = -1 ;
863
 
        char * lp_path ;//we have to free the result of ped_partition_get_path()..
864
888
        FS_Info fs_info ;  //Use cache of file system information
865
889
        DMRaid dmraid ;    //Use cache of dmraid device information
866
890
 
874
898
                partition_temp .Reset() ;
875
899
                bool partition_is_busy = false ;
876
900
 
 
901
                //Retrieve partition path
 
902
                Glib::ustring partition_path = get_partition_path( lp_partition );
 
903
 
877
904
                switch ( lp_partition ->type )
878
905
                {
879
906
                        case PED_PARTITION_NORMAL:
880
907
                        case PED_PARTITION_LOGICAL:
881
 
                                lp_path = ped_partition_get_path( lp_partition ) ;
882
 
 
883
908
                                //Handle dmraid devices differently because the minor number might not
884
909
                                //  match the last number of the partition filename as shown by "ls -l /dev/mapper"
885
910
                                //  This mismatch causes incorrect identification of busy partitions in ped_partition_is_busy(). 
898
923
                                        partition_is_busy = ped_partition_is_busy( lp_partition ) ;
899
924
 
900
925
                                partition_temp .Set( device .get_path(),
901
 
                                                     lp_path,
 
926
                                                     partition_path,
902
927
                                                     lp_partition ->num,
903
928
                                                     lp_partition ->type == 0 ? GParted::TYPE_PRIMARY : GParted::TYPE_LOGICAL,
904
929
                                                     get_filesystem(),
907
932
                                                     device .sector_size,
908
933
                                                     lp_partition ->type,
909
934
                                                     partition_is_busy ) ;
910
 
                                free( lp_path ) ;
911
 
                                                
 
935
 
912
936
                                partition_temp .add_paths( get_alternate_paths( partition_temp .get_path() ) ) ;
913
937
                                set_flags( partition_temp ) ;
914
 
                                
 
938
 
915
939
                                if ( partition_temp .busy && partition_temp .partition_number > device .highest_busy )
916
940
                                        device .highest_busy = partition_temp .partition_number ;
917
 
                                                                        
 
941
 
918
942
                                break ;
919
943
                        
920
944
                        case PED_PARTITION_EXTENDED:
921
 
                                lp_path = ped_partition_get_path( lp_partition ) ;
922
 
 
923
945
                                //Handle dmraid devices differently because the minor number might not
924
946
                                //  match the last number of the partition filename as shown by "ls -l /dev/mapper"
925
947
                                //  This mismatch causes incorrect identification of busy partitions in ped_partition_is_busy(). 
941
963
                                        partition_is_busy = ped_partition_is_busy( lp_partition ) ;
942
964
 
943
965
                                partition_temp .Set( device .get_path(),
944
 
                                                     lp_path, 
 
966
                                                     partition_path, 
945
967
                                                     lp_partition ->num,
946
968
                                                     GParted::TYPE_EXTENDED,
947
969
                                                     GParted::FS_EXTENDED,
950
972
                                                     device .sector_size,
951
973
                                                     false,
952
974
                                                     partition_is_busy ) ;
953
 
                                free( lp_path ) ;
954
 
                                
 
975
 
955
976
                                partition_temp .add_paths( get_alternate_paths( partition_temp .get_path() ) ) ;
956
977
                                set_flags( partition_temp ) ;
957
 
                                
 
978
 
958
979
                                EXT_INDEX = device .partitions .size() ;
959
980
                                break ;
960
 
                
 
981
 
961
982
                        default:
962
983
                                break;
963
984
                }
989
1010
                //next partition (if any)
990
1011
                lp_partition = ped_disk_next_partition( lp_disk, lp_partition ) ;
991
1012
        }
992
 
        
 
1013
 
993
1014
        if ( EXT_INDEX > -1 )
994
1015
                insert_unallocated( device .get_path(),
995
1016
                                    device .partitions[ EXT_INDEX ] .logicals,
1016
1037
        {
1017
1038
                ped_device_open( lp_device );
1018
1039
                ped_geometry_read( & lp_partition ->geom, buf, 0, 1 ) ;
1019
 
                strncpy(magic1, buf+0, 6) ;  magic1[6] = '\0' ; //set and terminate string
 
1040
                memcpy(magic1, buf+0, 6) ;  //set binary magic data
1020
1041
                ped_device_close( lp_device );
1021
1042
                free( buf ) ;
1022
1043
 
1023
 
                if ( Glib::ustring( magic1 ) == "LUKS\xBA\xBE" )
 
1044
                if ( 0 == memcmp( magic1 , "LUKS\xBA\xBE", 6 ) )
1024
1045
                {
1025
1046
                        temp = _( "Linux Unified Key Setup encryption is not yet supported." ) ;
1026
1047
                        temp += "\n" ;
1039
1060
 
1040
1061
                //TODO:  Temporary code to detect ext4.
1041
1062
                //       Replace when libparted >= 1.9.0 is chosen as minimum required version.
1042
 
                temp = fs_info .get_fs_type( Glib::ustring( ped_partition_get_path( lp_partition ) ) ) ;
1043
 
                if ( temp == "ext4" || temp == "ext4dev" )
1044
 
                        fs_type = temp ;
 
1063
                char * const path = ped_partition_get_path( lp_partition );
 
1064
 
 
1065
                if (NULL != path)
 
1066
                {
 
1067
                        temp = fs_info .get_fs_type( Glib::ustring( path ) ) ;
 
1068
                        if ( temp == "ext4" || temp == "ext4dev" )
 
1069
                                fs_type = temp ;
 
1070
                        free( path );
 
1071
                }
1045
1072
        }
1046
1073
 
1047
1074
        //FS_Info (blkid) file system detection because current libparted (v2.2) does not
1049
1076
        if ( fs_type .empty() )
1050
1077
        {
1051
1078
                //TODO: blkid does not return anything for an "extended" partition.  Need to handle this somehow
1052
 
                fs_type = fs_info .get_fs_type( Glib::ustring( ped_partition_get_path( lp_partition ) ) ) ;
 
1079
                char * const path = ped_partition_get_path( lp_partition );
 
1080
                if (NULL != path)
 
1081
                {
 
1082
                        fs_type = fs_info.get_fs_type( Glib::ustring( path ) ) ;
 
1083
                        free( path );
 
1084
                }
1053
1085
        }
1054
1086
 
1055
1087
        if ( ! fs_type .empty() )
1107
1139
                                 , (65536 / lp_device ->sector_size) 
1108
1140
                                 , 1
1109
1141
                                 ) ;
1110
 
                strncpy(magic1, buf+0, 7) ;  magic1[7] = '\0' ; //set and terminate string
 
1142
                memcpy(magic1, buf+0, 7) ; //set binary magic data
1111
1143
                ped_device_close( lp_device );
1112
1144
                free( buf ) ;
1113
1145
 
1114
 
                if ( Glib::ustring( magic1 ) == "ReIsEr4" )
 
1146
                if ( 0 == memcmp( magic1, "ReIsEr4", 7 ) )
1115
1147
                        return GParted::FS_REISER4 ;
1116
1148
        }
1117
1149
 
1124
1156
                if ( lp_device ->sector_size == 512 )
1125
1157
                {
1126
1158
                        ped_geometry_read( & lp_partition ->geom, buf, 1, 1 ) ;
1127
 
                        strncpy(magic1, buf+ 0, 8) ; magic1[8] = '\0' ; //set and terminate string
1128
 
                        strncpy(magic2, buf+24, 4) ; magic2[4] = '\0' ; //set and terminate string
 
1159
                        memcpy(magic1, buf+ 0, 8) ; // set binary magic data
 
1160
                        memcpy(magic2, buf+24, 4) ; // set binary magic data
1129
1161
                }
1130
1162
                else
1131
1163
                {
1132
1164
                        ped_geometry_read( & lp_partition ->geom, buf, 0, 1 ) ;
1133
 
                        strncpy(magic1, buf+ 0+512, 8) ; magic1[8] = '\0' ; //set and terminate string
1134
 
                        strncpy(magic2, buf+24+512, 4) ; magic2[4] = '\0' ; //set and terminate string
 
1165
                        memcpy(magic1, buf+ 0+512, 8) ; // set binary magic data
 
1166
                        memcpy(magic2, buf+24+512, 4) ; // set binary magic data
1135
1167
                }
1136
1168
                ped_device_close( lp_device );
1137
1169
                free( buf ) ;
1138
1170
 
1139
 
                if (    Glib::ustring( magic1 ) == "LABELONE"
1140
 
                     && Glib::ustring( magic2 ) == "LVM2" )
 
1171
                if (    0 == memcmp( magic1, "LABELONE", 8 )
 
1172
                     && 0 == memcmp( magic2, "LVM2", 4 ) )
1141
1173
                {
1142
1174
                        temp = _( "Logical Volume Management is not yet supported." ) ;
1143
1175
                        temp += "\n" ;
1149
1181
        //btrfs
1150
1182
        const Sector BTRFS_SUPER_INFO_SIZE   = 4096 ;
1151
1183
        const Sector BTRFS_SUPER_INFO_OFFSET = (64 * 1024) ;
1152
 
        const Glib::ustring BTRFS_SIGNATURE  = "_BHRfS_M" ;
 
1184
        const char* const BTRFS_SIGNATURE  = "_BHRfS_M" ;
1153
1185
 
1154
1186
        char    buf_btrfs[BTRFS_SUPER_INFO_SIZE] ;
1155
1187
 
1159
1191
                         , (BTRFS_SUPER_INFO_OFFSET / lp_device ->sector_size)
1160
1192
                         , (BTRFS_SUPER_INFO_SIZE / lp_device ->sector_size)
1161
1193
                         ) ;
1162
 
        strncpy(magic1, buf_btrfs+64, BTRFS_SIGNATURE .size()) ;  magic1[BTRFS_SIGNATURE .size()] = '\0' ; //set and terminate string
 
1194
        memcpy(magic1, buf_btrfs+64, strlen(BTRFS_SIGNATURE) ) ;  //set binary magic data
1163
1195
        ped_device_close( lp_device ) ;
1164
1196
 
1165
 
        if ( magic1 == BTRFS_SIGNATURE )
 
1197
        if ( 0 == memcmp( magic1, BTRFS_SIGNATURE, strlen(BTRFS_SIGNATURE) ) )
1166
1198
        {
1167
 
                temp = _( "BTRFS is not yet supported." ) ;
1168
 
                temp += "\n" ;
1169
 
                partition_temp .messages .push_back( temp ) ;
1170
1199
                return GParted::FS_BTRFS ;
1171
1200
        }
1172
1201
 
1269
1298
                     ) &&
1270
1299
                     partitions[ t ] .filesystem != GParted::FS_LINUX_SWAP &&
1271
1300
                     partitions[ t ] .filesystem != GParted::FS_LVM2 &&
1272
 
                     partitions[ t ] .filesystem != GParted::FS_LUKS &&
1273
 
                     partitions[ t ] .filesystem != GParted::FS_BTRFS
 
1301
                     partitions[ t ] .filesystem != GParted::FS_LUKS
1274
1302
                   )
1275
1303
                {
1276
1304
                        if ( partitions[ t ] .busy )
1331
1359
        for ( unsigned int t = 0 ; t < partitions .size() ; t++ )
1332
1360
        {
1333
1361
                if ( partitions[ t ] .filesystem != GParted::FS_LINUX_SWAP &&
1334
 
                     partitions[ t ] .filesystem != GParted::FS_BTRFS &&
1335
1362
                     partitions[ t ] .filesystem != GParted::FS_LUKS &&
1336
1363
                     partitions[ t ] .filesystem != GParted::FS_LVM2 &&
1337
1364
                     partitions[ t ] .filesystem != GParted::FS_UNKNOWN
1511
1538
                
1512
1539
                                if ( ped_disk_add_partition( lp_disk, lp_partition, constraint ) && commit() )
1513
1540
                                {
1514
 
                                        //we have to free the result of ped_partition_get_path()..
1515
 
                                        char * lp_path = ped_partition_get_path( lp_partition ) ;
1516
 
                                        new_partition .add_path( lp_path, true ) ;
1517
 
                                        free( lp_path ) ;
 
1541
                                        Glib::ustring partition_path = get_partition_path( lp_partition ) ;
 
1542
                                        new_partition .add_path( partition_path, true ) ;
1518
1543
 
1519
1544
                                        new_partition .partition_number = lp_partition ->num ;
1520
1545
                                        new_partition .sector_start = lp_partition ->geom .start ;
1712
1737
{
1713
1738
        if ( partition_old .get_sector_length() != partition_new .get_sector_length() )
1714
1739
        {       
1715
 
                operationdetail .add_child( OperationDetail( 
1716
 
                        _("moving requires old and new length to be the same"), STATUS_ERROR, FONT_ITALIC ) ) ;
 
1740
                operationdetail .add_child( OperationDetail(
 
1741
                                /* TO TRANSLATORS:  moving requires old and new length to be the same
 
1742
                                 * means that the length in bytes of the old partition and new partition
 
1743
                                 * must be the same.  If the sector sizes of the old partition and the
 
1744
                                 * new partition are the same, then the length in sectors must be the same.
 
1745
                                 */
 
1746
                                _("moving requires old and new length to be the same"), STATUS_ERROR, FONT_ITALIC ) ) ;
1717
1747
 
1718
1748
                return false ;
1719
1749
        }
1830
1860
                                                                         operationdetail .get_last_child() ) ;
1831
1861
                        break ;
1832
1862
                case GParted::FS::EXTERNAL:
 
1863
                        succes = set_proper_filesystem( partition_new .filesystem ) &&
 
1864
                                 p_filesystem ->move( partition_old
 
1865
                                                    , partition_new
 
1866
                                                    , operationdetail .get_last_child()
 
1867
                                                    ) ;
1833
1868
                        break ;
1834
1869
        }
1835
1870
 
2409
2444
bool GParted_Core::check_repair_filesystem( const Partition & partition, OperationDetail & operationdetail ) 
2410
2445
{
2411
2446
        operationdetail .add_child( OperationDetail( 
2412
 
                                String::ucompose( _("check file system on %1 for errors and (if possible) fix them"),
 
2447
                                String::ucompose(
 
2448
                                                /* TO TRANSLATORS: looks like   check file system on /dev/sda5 for errors and (if possible) fix them */
 
2449
                                                _("check file system on %1 for errors and (if possible) fix them"),
2413
2450
                                                  partition .get_path() ) ) ) ;
2414
2451
        
2415
2452
        bool succes = false ;
2832
2869
 
2833
2870
bool GParted_Core::set_proper_filesystem( const FILESYSTEM & filesystem )
2834
2871
{
2835
 
        if ( p_filesystem )
2836
 
                delete p_filesystem ;
 
2872
        delete p_filesystem;
2837
2873
                
2838
2874
        switch( filesystem )
2839
2875
        {
 
2876
                case FS_BTRFS           : p_filesystem = new btrfs() ;          break ;
2840
2877
                case FS_EXT2            : p_filesystem = new ext2() ;           break ;
2841
2878
                case FS_EXT3            : p_filesystem = new ext3() ;           break ;
2842
2879
                case FS_EXT4            : p_filesystem = new ext4() ;           break ;
2851
2888
                case FS_HFS             : p_filesystem = new hfs() ;            break ;
2852
2889
                case FS_HFSPLUS         : p_filesystem = new hfsplus() ;        break ;
2853
2890
                case FS_UFS             : p_filesystem = new ufs() ;            break ;
2854
 
 
2855
2891
                default                 : p_filesystem = NULL ;
2856
2892
        }
2857
2893
 
2872
2908
                        if ( ped_device_open( lp_device ) )
2873
2909
                        {
2874
2910
                                //reiser4 stores "ReIsEr4" at sector 128 with a sector size of 512 bytes
 
2911
                                // FIXME writing block of partially uninitialized bytes (security/privacy)
2875
2912
                                return_value = ped_geometry_write( & lp_partition ->geom, "0000000", (65536 / lp_device ->sector_size), 1 ) ;
2876
2913
 
2877
2914
                                ped_device_close( lp_device ) ;
3073
3110
 
3074
3111
GParted_Core::~GParted_Core() 
3075
3112
{
3076
 
        if ( p_filesystem )
3077
 
                delete p_filesystem ;
 
3113
        delete p_filesystem;
3078
3114
}
3079
3115
        
3080
3116
} //GParted