~teejee2008/timeshift/trunk

« back to all changes in this revision

Viewing changes to src/Utility/Device.vala

  • Committer: Tony George
  • Date: 2016-11-01 12:07:45 UTC
  • Revision ID: tony.george.kol@gmail.com-20161101120745-rqdl2p6125cgp428
RestoreWindow: Fixed some issues in device selection logic; Comboboxes would remain unselected in some scenarios; User will be prompted to unlock default devices before the restore window is displayed;

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
        public static double MiB = 1024 * KiB;
42
42
        public static double GiB = 1024 * MiB;
43
43
        
44
 
        //GUdev.Device udev_device;
45
44
        public string device = "";
46
45
        public string kname = "";
47
46
        public string pkname = "";
49
48
        public string mapped_name = "";
50
49
        
51
50
        public string type = ""; // disk, part, crypt, loop, rom, lvm
52
 
        public string fstype = "";
 
51
        public string fstype = ""; // iso9660, ext4, btrfs, ...
53
52
 
54
53
        public string label = "";
55
54
        public string uuid = "";
199
198
 
200
199
        // static --------------------------------
201
200
        
202
 
        public static Gee.ArrayList<Device> get_filesystems(
203
 
                bool get_space = true,
204
 
                bool get_mounts = true){
 
201
        public static Gee.ArrayList<Device> get_filesystems(bool get_space = true, bool get_mounts = true){
205
202
 
206
203
                /* Returns list of block devices
207
204
                   Populates all fields in Device class */
321
318
                }
322
319
        }
323
320
 
324
 
        public static Gee.ArrayList<Device> get_block_devices_using_lsblk(
325
 
                string device_file = ""){
 
321
        public static Gee.ArrayList<Device> get_block_devices_using_lsblk(string dev_name = ""){
326
322
 
327
323
                /* Returns list of mounted partitions using 'lsblk' command
328
324
                   Populates device, type, uuid, label */
345
341
                        cmd = "lsblk --bytes --pairs --output NAME,KNAME,LABEL,UUID,TYPE,FSTYPE,SIZE,MOUNTPOINT,MODEL,RO,HOTPLUG,PKNAME,VENDOR,SERIAL,REV";
346
342
                }
347
343
 
348
 
                if (device_file.length > 0){
349
 
                        cmd += " %s".printf(device_file);
 
344
                if (dev_name.length > 0){
 
345
                        cmd += " %s".printf(dev_name);
350
346
                }
351
347
 
352
348
                if (LOG_DEBUG){
520
516
        }
521
517
 
522
518
        // deprecated: use get_block_devices_using_lsblk() instead
523
 
        public static Gee.ArrayList<Device> get_block_devices_using_blkid(
524
 
                string device_file = ""){
 
519
        public static Gee.ArrayList<Device> get_block_devices_using_blkid(string dev_name = ""){
525
520
 
526
521
                /* Returns list of mounted partitions using 'blkid' command
527
522
                   Populates device, type, uuid, label */
535
530
                Regex rex;
536
531
                MatchInfo match;
537
532
 
538
 
                cmd = "/sbin/blkid" + ((device_file.length > 0) ? " " + device_file: "");
 
533
                cmd = "/sbin/blkid" + ((dev_name.length > 0) ? " " + dev_name: "");
539
534
 
540
535
                if (LOG_DEBUG){
541
536
                        log_debug(cmd);
544
539
                ret_val = exec_script_sync(cmd, out std_out, out std_err);
545
540
                if (ret_val != 0){
546
541
                        var msg = "blkid: " + _("Failed to get partition list");
547
 
                        msg += (device_file.length > 0) ? ": " + device_file : "";
 
542
                        msg += (dev_name.length > 0) ? ": " + dev_name : "";
548
543
                        log_error(msg);
549
544
                        return list; //return empty list
550
545
                }
619
614
                return list;
620
615
        }
621
616
 
622
 
        public static Gee.ArrayList<Device> get_disk_space_using_df(
623
 
                string device_or_mount_point = ""){
 
617
        public static Gee.ArrayList<Device> get_disk_space_using_df(string dev_name_or_mount_point = ""){
624
618
 
625
619
                /*
626
620
                Returns list of mounted partitions using 'df' command
636
630
 
637
631
                cmd = "df -T -B1";
638
632
 
639
 
                if (device_or_mount_point.length > 0){
640
 
                        cmd += " '%s'".printf(escape_single_quote(device_or_mount_point));
 
633
                if (dev_name_or_mount_point.length > 0){
 
634
                        cmd += " '%s'".printf(escape_single_quote(dev_name_or_mount_point));
641
635
                }
642
636
 
643
637
                if (LOG_DEBUG){
932
926
                return "";
933
927
        }
934
928
 
935
 
        public static Gee.ArrayList<MountEntry> get_device_mount_points(string device_or_uuid){
 
929
        public static Gee.ArrayList<MountEntry> get_device_mount_points(string dev_name_or_uuid){
936
930
                string device = "";
937
931
                string uuid = "";
938
932
 
939
 
                if (device_or_uuid.has_prefix("/dev")){
940
 
                        device = device_or_uuid;
941
 
                        uuid = get_device_uuid(device_or_uuid);
 
933
                if (dev_name_or_uuid.has_prefix("/dev")){
 
934
                        device = dev_name_or_uuid;
 
935
                        uuid = get_device_uuid(dev_name_or_uuid);
942
936
                }
943
937
                else{
944
 
                        uuid = device_or_uuid;
 
938
                        uuid = dev_name_or_uuid;
945
939
                        device = "/dev/disk/by-uuid/%s".printf(uuid);
946
940
                        device = resolve_device_name(device);
947
941
                }
958
952
                }
959
953
        }
960
954
 
961
 
        public static bool device_is_mounted(string device_or_uuid){
 
955
        public static bool device_is_mounted(string dev_name_or_uuid){
962
956
 
963
 
                var mps = Device.get_device_mount_points(device_or_uuid);
 
957
                var mps = Device.get_device_mount_points(dev_name_or_uuid);
964
958
                if (mps.size > 0){
965
959
                        return true;
966
960
                }
981
975
                return false;
982
976
        }
983
977
 
984
 
        public static string resolve_device_name(string dev_device){
 
978
        public static string resolve_device_name(string dev_alias){
985
979
 
986
 
                string resolved = dev_device;
 
980
                string resolved = dev_alias;
987
981
                
988
 
                if (dev_device.has_prefix("/dev/mapper/")){
989
 
                        var link_path = file_get_symlink_target(dev_device);
 
982
                if (dev_alias.has_prefix("/dev/mapper/")){
 
983
                        var link_path = file_get_symlink_target(dev_alias);
990
984
                        if (link_path.has_prefix("../")){
991
985
                                resolved = link_path.replace("../","/dev/");
992
986
                        }
993
987
                }
994
988
 
995
 
                if (dev_device.has_prefix("/dev/disk/")){
996
 
                        var link_path = file_get_symlink_target(dev_device);
 
989
                if (dev_alias.has_prefix("/dev/disk/")){
 
990
                        var link_path = file_get_symlink_target(dev_alias);
997
991
                        if (link_path.has_prefix("../../")){
998
992
                                resolved = link_path.replace("../../","/dev/");
999
993
                        }
1000
994
                }
1001
995
 
1002
 
                if (dev_device != resolved){
1003
 
                        //log_msg("resolved '%s' to '%s'".printf(dev_device, resolved));
 
996
                if (dev_alias != resolved){
 
997
                        //log_msg("resolved '%s' to '%s'".printf(dev_alias, resolved));
1004
998
                }
1005
999
 
1006
1000
                return resolved;
1078
1072
 
1079
1073
        // mounting ---------------------------------
1080
1074
        
1081
 
        public static bool automount_udisks(string device_name_or_uuid, Gtk.Window? parent_window){
 
1075
        public static bool automount_udisks(string dev_name_or_uuid, Gtk.Window? parent_window){
1082
1076
                
1083
 
                if (device_name_or_uuid.length == 0){
 
1077
                if (dev_name_or_uuid.length == 0){
1084
1078
                        log_error(_("Device name is empty!"));
1085
1079
                        return false;
1086
1080
                }
1087
1081
                
1088
 
                var cmd = "udisksctl mount -b '%s'".printf(device_name_or_uuid);
 
1082
                var cmd = "udisksctl mount -b '%s'".printf(dev_name_or_uuid);
1089
1083
                log_debug(cmd);
1090
1084
                int status = Posix.system(cmd);
1091
1085
 
1092
1086
                if (status != 0){
1093
1087
                        if (parent_window != null){
1094
 
                                string msg = "Failed to mount: %s".printf(device_name_or_uuid);
 
1088
                                string msg = "Failed to mount: %s".printf(dev_name_or_uuid);
1095
1089
                                gtk_messagebox("Error", msg, parent_window, true);
1096
1090
                        }
1097
1091
                }
1140
1134
                return false;
1141
1135
        }
1142
1136
 
1143
 
        public static bool unmount_udisks(string device_name_or_uuid, Gtk.Window? parent_window){
 
1137
        public static bool unmount_udisks(string dev_name_or_uuid, Gtk.Window? parent_window){
1144
1138
 
1145
 
                if (device_name_or_uuid.length == 0){
 
1139
                if (dev_name_or_uuid.length == 0){
1146
1140
                        log_error(_("Device name is empty!"));
1147
1141
                        return false;
1148
1142
                }
1149
1143
                
1150
 
                var cmd = "udisksctl unmount -b '%s'".printf(device_name_or_uuid);
 
1144
                var cmd = "udisksctl unmount -b '%s'".printf(dev_name_or_uuid);
1151
1145
                log_debug(cmd);
1152
1146
                int status = Posix.system(cmd);
1153
1147
 
1154
1148
                if (status != 0){
1155
1149
                        if (parent_window != null){
1156
 
                                string msg = "Failed to unmount: %s".printf(device_name_or_uuid);
 
1150
                                string msg = "Failed to unmount: %s".printf(dev_name_or_uuid);
1157
1151
                                gtk_messagebox("Error", msg, parent_window, true);
1158
1152
                        }
1159
1153
                }
1182
1176
                }
1183
1177
 
1184
1178
                // check if already unlocked
1185
 
                var list = get_filesystems();
 
1179
                var list = get_block_devices_using_lsblk();
1186
1180
                foreach(var part in list){
1187
1181
                        if (part.pkname == luks_device.kname){
1188
1182
                                unlocked_device = part;
1287
1281
                }
1288
1282
 
1289
1283
                // find unlocked device
1290
 
                list = get_filesystems();
 
1284
                list = get_block_devices_using_lsblk();
1291
1285
                foreach(var part in list){
1292
1286
                        if (part.pkname == luks_device.kname){
1293
1287
                                unlocked_device = part;
1345
1339
        }
1346
1340
 
1347
1341
        public static bool mount(
1348
 
                string device_or_uuid, string mount_point, string mount_options = "", bool silent = false){
 
1342
                string dev_name_or_uuid, string mount_point, string mount_options = "", bool silent = false){
1349
1343
 
1350
1344
                /*
1351
1345
                 * Mounts specified device at specified mount point.
1360
1354
                string device = "";
1361
1355
                string uuid = "";
1362
1356
 
1363
 
                if (device_or_uuid.has_prefix("/dev")){
1364
 
                        device = device_or_uuid;
1365
 
                        uuid = get_device_uuid(device_or_uuid);
 
1357
                if (dev_name_or_uuid.has_prefix("/dev")){
 
1358
                        device = dev_name_or_uuid;
 
1359
                        uuid = get_device_uuid(dev_name_or_uuid);
1366
1360
                }
1367
1361
                else{
1368
 
                        uuid = device_or_uuid;
 
1362
                        uuid = dev_name_or_uuid;
1369
1363
                        device = "/dev/disk/by-uuid/%s".printf(uuid);
 
1364
                        device = resolve_device_name(device);
1370
1365
                }
1371
1366
 
1372
1367
                if (dir_exists(mount_point)){
1375
1370
                
1376
1371
                // check if already mounted ------------------
1377
1372
                
1378
 
                var mps = Device.get_device_mount_points(device_or_uuid);
 
1373
                var mps = Device.get_device_mount_points(dev_name_or_uuid);
1379
1374
                foreach(var mp in mps){
1380
1375
                        if (mp.mount_point.contains(mount_point)){
1381
1376
                                if (!silent){
1382
1377
                                        string msg = "";
1383
 
                                        msg += "%s: %s %s".printf(_("Mounted"), _("device"), device_or_uuid);
 
1378
                                        msg += "%s: %s %s".printf(_("Mounted"), _("device"), dev_name_or_uuid);
1384
1379
                                        if (mp.mount_options.length > 0){
1385
1380
                                                msg += ", %s".printf(mp.mount_options);
1386
1381
                                        }
1433
1428
 
1434
1429
                // check if mounted successfully ------------------
1435
1430
 
1436
 
                /*mps = Device.get_device_mount_points(device_or_uuid);
 
1431
                /*mps = Device.get_device_mount_points(dev_name_or_uuid);
1437
1432
                if (mps.contains(mount_point)){
1438
 
                        log_msg("Device '%s' is mounted at '%s'".printf(device_or_uuid, mount_point));
 
1433
                        log_msg("Device '%s' is mounted at '%s'".printf(dev_name_or_uuid, mount_point));
1439
1434
                        return true;
1440
1435
                }
1441
1436
                else{
1444
1439
        }
1445
1440
 
1446
1441
        public static string automount(
1447
 
                string device_or_uuid, string mount_options = "", string mount_prefix = "/mnt"){
 
1442
                string dev_name_or_uuid, string mount_options = "", string mount_prefix = "/mnt"){
1448
1443
 
1449
1444
                /* Returns the mount point of specified device.
1450
1445
                 * If unmounted, mounts the device to /mnt/<uuid> and returns the mount point.
1455
1450
 
1456
1451
                // get uuid -----------------------------
1457
1452
 
1458
 
                if (device_or_uuid.has_prefix("/dev")){
1459
 
                        device = device_or_uuid;
1460
 
                        uuid = Device.get_device_uuid(device_or_uuid);
 
1453
                if (dev_name_or_uuid.has_prefix("/dev")){
 
1454
                        device = dev_name_or_uuid;
 
1455
                        uuid = Device.get_device_uuid(dev_name_or_uuid);
1461
1456
                }
1462
1457
                else{
1463
 
                        uuid = device_or_uuid;
 
1458
                        uuid = dev_name_or_uuid;
1464
1459
                        device = "/dev/disk/by-uuid/%s".printf(uuid);
 
1460
                        device = resolve_device_name(device);
1465
1461
                }
1466
1462
 
1467
1463
                // check if already mounted and return mount point -------------
1761
1757
                return "<tt>%s</tt>".printf(tt);
1762
1758
        }
1763
1759
 
 
1760
        private string display_name(bool short_name = true, bool show_label = true, bool show_parent = true, bool show_alias = false){
 
1761
        
 
1762
                string txt = "";
 
1763
 
 
1764
                if (short_name){
 
1765
                        txt += kname;
 
1766
                }
 
1767
                else{
 
1768
                        txt += device;
 
1769
                }
 
1770
 
 
1771
                if (type == "disk"){
 
1772
                        if (vendor.length > 0){
 
1773
                                txt += " " + vendor;
 
1774
                        }
 
1775
                        if (model.length > 0){
 
1776
                                txt += " " + model;
 
1777
                        }
 
1778
                        if (size_bytes > 0) {
 
1779
                                if (txt.strip().length == 0){
 
1780
                                        txt += "%s Device".printf(format_file_size(size_bytes, false, "", true, 0));
 
1781
                                }
 
1782
                                else{
 
1783
                                        txt += " (%s)".printf(format_file_size(size_bytes, false, "", true, 0));
 
1784
                                }
 
1785
                        }
 
1786
                }
 
1787
                else{
 
1788
                        if (show_label && (label.length > 0)){
 
1789
                                txt += "(%s)".printf(label);
 
1790
                        }
 
1791
                        if (show_parent && has_parent() && (parent.type == "part")){ // TODO: if parent is crypt (like lvm on luks)
 
1792
                                txt += "(%s)".printf(pkname);
 
1793
                        }
 
1794
                        if (show_alias && (mapped_name.length > 0)){
 
1795
                                txt += "(%s)".printf(mapped_name);
 
1796
                        }
 
1797
                }
 
1798
                
 
1799
                return txt;
 
1800
        }       
 
1801
        
1764
1802
        // testing -----------------------------------
1765
1803
 
1766
1804
        public static void test_all(){
1799
1837
 
1800
1838
                log_debug("");
1801
1839
                
1802
 
                log_debug("%-20s %-10s %-10s %-36s %s".printf(
 
1840
                log_debug("%-12s ,%-5s ,%-5s ,%-36s ,%s".printf(
1803
1841
                        "device",
1804
1842
                        "pkname",
1805
1843
                        "kname",
1809
1847
                log_debug(string.nfill(100, '-'));
1810
1848
 
1811
1849
                foreach(var dev in list){
1812
 
                        log_debug("%-20s %-10s %-10s %-36s %s".printf(
 
1850
                        log_debug("%-12s ,%-5s ,%-5s ,%-36s ,%s".printf(
1813
1851
                                dev.device ,
1814
1852
                                dev.pkname,
1815
1853
                                dev.kname,
1845
1883
                log_debug("");
1846
1884
                */
1847
1885
                
1848
 
                log_debug("%-20s %-10s %-15s %-3s %-3s %15s %15s".printf(
 
1886
                /*log_debug("%-20s %-10s %-15s %-3s %-3s %15s %15s".printf(
1849
1887
                        "device",
1850
1888
                        "type",
1851
1889
                        "fstype",
1866
1904
                                format_file_size(dev.size_bytes, true),
1867
1905
                                format_file_size(dev.used_bytes, true)
1868
1906
                                ));
1869
 
                }
 
1907
                }*/
1870
1908
 
1871
 
                log_debug("");
 
1909
                //log_debug("");
1872
1910
        }
1873
1911
 
1874
1912
        public static void print_device_mounts(Gee.ArrayList<Device> list){