source: MondoRescue/branches/2.2.10/mondo/src/common/libmondo-mountlist.c@ 2508

Last change on this file since 2508 was 2508, checked in by Bruno Cornec, 14 years ago

r3287@localhost (orig r2285): bruno | 2009-07-20 11:36:47 +0200

r3285@localhost: bruno | 2009-07-20 11:17:35 +0200
Apply fix in 2.2.10 around multi USB device handling to 2.2.9 as well


r3291@localhost (orig r2288): bruno | 2009-07-21 16:48:31 +0200
Copy 2.2.10 test script in to 2.2.9 for memory problm analysis


r3293@localhost (orig r2290): bruno | 2009-07-22 14:03:44 +0200

  • Fix a printing error in mindi for the tar command
  • Fix all mr_asprintf which had no second param as a string


r3295@localhost (orig r2292): bruno | 2009-07-22 16:55:00 +0200

  • Fix #160 and #346 by rewriting the message.txt file with more valid information gathered in mindi


r3300@localhost (orig r2294): bruno | 2009-07-23 01:58:08 +0200

Man pages patch from Joe Ross (joe.ross_at_gmail.com)


r3303@localhost (orig r2297): bruno | 2009-07-23 17:43:49 +0200
Fix a remaining display error for 2.2.9. That version has been tested OK in a lab.


r3304@localhost (orig r2298): bruno | 2009-07-23 18:18:27 +0200

  • Remove memory leak for the last modification


r3308@localhost (orig r2302): bruno | 2009-07-24 21:18:50 +0200
Improve logging of mountlist.txt


r3310@localhost (orig r2304): bruno | 2009-07-27 19:45:10 +0200

  • popup_and_get_string needs an allocated buffer for the moment so fixing the calls with dyn. ones
  • Fix a bug in mem.c for mr_strcat, which wasn't modifying the right pointer level


r3311@localhost (orig r2305): bruno | 2009-07-27 19:49:35 +0200
Avoid a memory leak in the previous patch


r3314@localhost (orig r2308): bruno | 2009-07-27 20:59:06 +0200
Fix a bug in mr_strcat backported from 2.2.10. Should solve our seg faults.


r3315@localhost (orig r2309): bruno | 2009-07-28 02:14:23 +0200
Cosmetic changes to allow for quality to not giv false positive


r3343@localhost (orig r2311): bruno | 2009-08-18 02:13:43 +0200
Fix for initramfs detection with 2.6.30 (Hugo Vanwoerkom hvw59601_at_care2.com)


r3367@localhost (orig r2333): bruno | 2009-08-18 16:26:26 +0200
Adds a precision for -U option in man page on raw device usage and not partition name


r3373@localhost (orig r2336): bruno | 2009-08-20 17:37:41 +0200

  • Precise the combined usage of -E and -I in mondoarchive (Case 4601017223)


r3379@localhost (orig r2342): bruno | 2009-08-21 16:27:10 +0200


r3383@localhost (orig r2344): bruno | 2009-08-24 13:37:09 +0200

r3382@localhost: bruno | 2009-08-24 13:30:25 +0200
In NFS mode also propose access to expert, interactive, ... entry at boot prompt


r3388@localhost (orig r2346): bruno | 2009-08-27 11:41:16 +0200
Adds fdisk -l result in Log File at restore time


r3389@localhost (orig r2347): bruno | 2009-08-27 13:51:00 +0200

  • Solve tmp dir creation which sometimes was trying to create /%xx dirs. Should fix #293 for good


r3390@localhost (orig r2348): bruno | 2009-08-27 13:54:25 +0200
Improve logging (minor)


r3394@localhost (orig r2350): bruno | 2009-08-28 02:24:19 +0200
Change inerface of evaluate_mountlist and spread_flaws_across_three_lines in order to solve bugs linked to strings management in these functions. May fix a restoration crash seen by some customers


r3397@localhost (orig r2353): bruno | 2009-08-28 19:03:45 +0200

  • Addition of a nomd option to avoid starting mdadm
  • mpath is now already started if there was a mpath entry in mountlist


r3399@localhost (orig r2355): bruno | 2009-08-29 00:56:50 +0200
Remove function spread_flaws_across_three_lines and expand it at the single place where it was useful, and fix memory allocation issues in it.


r3402@localhost (orig r2358): bruno | 2009-09-01 19:02:35 +0200
P2V doc updated (Lester Wade lester.wade_at_hp.com)


r3404@localhost (orig r2360): bruno | 2009-09-01 19:26:53 +0200
Website update to refer to new P2V document


r3405@localhost (orig r2361): bruno | 2009-09-03 13:54:25 +0200

  • Fix a case where the NFS dir in restore mode was mounted rw (linked to bug #291 could create a huge problem)


r3407@localhost (orig r2363): bruno | 2009-09-03 14:46:46 +0200
More verbose at installation of additional tools


r3409@localhost (orig r2365): bruno | 2009-09-03 18:08:32 +0200

  • New update from Lester Wade (lester.wade_at_hp.com) for P2V doc


r3410@localhost (orig r2366): bruno | 2009-09-05 01:28:18 +0200
place the code of mondo_makefilelist before its call



r3411@localhost (orig r2367): bruno | 2009-09-06 01:51:26 +0200

  • Advertising for project-builder on the website added


r3412@localhost (orig r2368): bruno | 2009-09-07 15:36:23 +0200
Fix compilation issue


r3413@localhost (orig r2369): bruno | 2009-09-07 18:03:40 +0200
Another compilation issue fixed.


r3415@localhost (orig r2371): bruno | 2009-09-08 13:40:25 +0200

  • Fix a problem a error detection in evaluate_mountlist which casued nuke mode to abort. Error string should also be better now.


r3417@localhost (orig r2373): bruno | 2009-09-08 13:55:31 +0200
Avoid asking the Prefix name in NFS mode twice


r3418@localhost (orig r2374): bruno | 2009-09-08 20:04:07 +0200

  • Try to fix garbled screen progression in text mode based on 2.2.10 modifications which are working


r3424@localhost (orig r2380): bruno | 2009-09-09 20:30:47 +0200

  • Change NFS support into a NetFS support to allow for multiple protocol in addition to NFS (NEEDS TESTING)
  • Better logging to detect a potential nuke issue


r3425@localhost (orig r2381): bruno | 2009-09-10 02:05:55 +0200
Fix a missing param for sshfs call


r3428@localhost (orig r2384): bruno | 2009-09-10 13:02:56 +0200

  • Remove separate function look_for_duplicate_mountpoints used only once and whose interface created problems with caller


r3430@localhost (orig r2386): bruno | 2009-09-10 16:06:52 +0200
Be compatible on backup type by making old nfs recognized as netfs and proto forced


r3431@localhost (orig r2387): bruno | 2009-09-10 18:40:47 +0200
Fix a problem in netfs analysis in mondoarchive


r3432@localhost (orig r2388): bruno | 2009-09-10 20:25:13 +0200
Fix mondoarchive CLI analysis for NETFS type of requests


r3434@localhost (orig r2390): bruno | 2009-09-11 03:05:20 +0200

  • Adds ext3 initrd support for 2.6.30


r3437@localhost (orig r2393): bruno | 2009-09-11 11:56:52 +0200

  • Tries to add support for bzip2 and lzma initramfs (preliminary, not tested) for 2.6.30


r3438@localhost (orig r2394): bruno | 2009-09-12 02:53:02 +0200
Fix interface of evaluate_mountlist (remove 2nd param useless) and fix nuke mode which wasn't working.


r3441@localhost (orig r2397): bruno | 2009-09-14 18:54:34 +0200
Fix a format issue in text mode on percentage


r3452@localhost (orig r2398): bruno | 2009-09-15 16:00:13 +0200

  • Fix a bug where flaws_str could be NULL and wasn't tested correctly.


r3453@localhost (orig r2399): bruno | 2009-09-15 19:28:39 +0200

  • Use protocol name when displaying restore progress instead of netfs
  • Ask for network protocol name at restore time


r3455@localhost (orig r2401): bruno | 2009-09-15 19:34:19 +0200
Wrong structure member name was used


r3456@localhost (orig r2402): bruno | 2009-09-16 13:04:17 +0200
Use dir for shell related commands and dir1 for C related actions in open_and_list_dir to avoid missing some files with { in names e.g.


r3457@localhost (orig r2403): bruno | 2009-09-16 16:32:03 +0200

  • At restore time read the netfs protocol in the conf file


r3462@localhost (orig r2408): bruno | 2009-09-18 15:17:08 +0200
Remove useless script


r3463@localhost (orig r2409): bruno | 2009-09-18 15:25:35 +0200

  • Split deplist.txt into multiple conf files under deplist.d in the conf dir. This will allow to have a minimal.conf file for initrd content to analyze to improve support of new embedded feature in the future (sshfs, live install). The other conf files contain the additional commands to put in the all.tar.gz. For the moment, mindi is still working the same. THis infra will allow that support in a near future. deplist.txt is now reserved for the admin additional commands.


r3465@localhost (orig r2410): bruno | 2009-09-18 19:10:54 +0200

  • Better list of mandatory tools
  • Adds fuse and sshfs support in initrd


r3466@localhost (orig r2411): bruno | 2009-09-18 20:32:47 +0200
sshfs also needs ssh at restore time in initrd


r3478@localhost (orig r2418): bruno | 2009-09-23 23:22:39 +0200
Modify getfattr call to have all extended attributes, including non user ones. (patch from Kevin Ritzenthaler Kevin.Ritzenthaler_at_hp.com) and fix #357


r3479@localhost (orig r2419): bruno | 2009-09-23 23:50:34 +0200
star only supports ACL when used with exustar mode. Fix #356.


r3482@localhost (orig r2422): bruno | 2009-09-24 16:53:24 +0200

  • Adds support for bnx2x (BL 460 G6) and auth_rpcgss (Debian 2.6.31)


r3485@localhost (orig r2423): bruno | 2009-09-25 16:38:40 +0200
Fix an issue in is_this_device_mounted (string freed before last usage)


r3486@localhost (orig r2424): bruno | 2009-09-25 18:44:01 +0200

  • analyze-my-lvm now removes excluded devices from list coming from mondoarchive
  • new mr_make_devlist_from_pathlist which handle the new bkpinfo->exclude_devs field containing the excluded devices and remove corresponding code from libmondo-cli.c
  • Move DSF code into libmondo-devices.c for coherency, and only the previous function is made externally available
  • Remove dev_to_exclude in libmondo-archive.c which wasn't working correctly and replace it with bkpinfo->exclude_devs


r3487@localhost (orig r2425): bruno | 2009-09-25 18:58:23 +0200

  • Improving ssh support at restore time by providing a shadow file


r3489@localhost (orig r2426): bruno | 2009-09-25 19:42:09 +0200

  • Attempt to stay backward compatible without protocol for -n option


r3490@localhost (orig r2427): bruno | 2009-09-28 02:08:06 +0200
Avoids null param for excludes_devs for mindi call


r3492@localhost (orig r2429): bruno | 2009-09-28 11:46:16 +0200

  • Simplify GetInitrdFilesystemToUse which doesn't need to detect everything, but just know if it's initramfs (new mode) or a compressed FS ext2/3 (older mode) as initrd is anyway re-made by mindi. Should fix #353


r3494@localhost (orig r2431): bruno | 2009-09-28 13:16:18 +0200

  • Use only the AWK veriable everywhere and not the awk command


r3495@localhost (orig r2432): bruno | 2009-09-28 14:16:31 +0200
Warning emited in case of duplicate mountpoints or devices in fstab found


r3496@localhost (orig r2433): bruno | 2009-09-28 15:55:17 +0200
ssh in the restore env needs some dlopened libs (libnss_compat|files)


r3497@localhost (orig r2434): bruno | 2009-09-28 16:33:14 +0200
Compiler warning fixed


r3498@localhost (orig r2435): bruno | 2009-09-28 17:55:26 +0200
Improve user management for NetFS cases


r3499@localhost (orig r2436): bruno | 2009-09-29 01:48:32 +0200

  • Improve deplist.d/* files
  • adds libnss for ssh support in boot disk
  • Solve a memory management issue in DSF module (strtok => mr_strtok)
  • DSF now also supports partitions in addition to full disks
  • Adds debug in open_and_list_dir


r3500@localhost (orig r2437): bruno | 2009-09-29 10:41:56 +0200

  • Fix udev support in init for Mandriva 2009.1 (udevadm settle is blocking)


r3501@localhost (orig r2438): bruno | 2009-09-29 14:41:36 +0200

  • Improvements on sshfs/ssh management in restore mode
  • Include now all minimal requirements for sshfs


r3502@localhost (orig r2439): bruno | 2009-09-29 18:46:08 +0200

  • Avoids error message if some ssh conf files do not exist


r3503@localhost (orig r2440): bruno | 2009-09-29 18:57:13 +0200

  • Avoids comment analysis in the new code handling deplist.d


r3504@localhost (orig r2441): bruno | 2009-09-29 19:34:34 +0200

  • fuse device is needed at restore time for sshfs


r3505@localhost (orig r2442): bruno | 2009-09-29 20:02:36 +0200

  • Improves udev timeout handling


r3506@localhost (orig r2443): bruno | 2009-09-29 20:43:38 +0200

  • priority given to env var for tmpdir
  • fuse FS excluded from tmpdir computation


r3518@localhost (orig r2447): bruno | 2009-10-04 01:58:08 +0200

  • Iprove USB log in case of error by adding the conf file


r3519@localhost (orig r2448): bruno | 2009-10-05 11:06:13 +0200


r3520@localhost (orig r2449): bruno | 2009-10-06 01:10:35 +0200

  • Adds support for grub2 conf file grub.cfg in addition to menu.lst


r3521@localhost (orig r2450): bruno | 2009-10-06 01:24:02 +0200

  • Fix a mr_asprintf usage without & causing a seg fault.


r3523@localhost (orig r2452): bruno | 2009-10-06 12:47:56 +0200
CIFS mounts shouldn't be part of the mountlist analysis (should help solving #288)


r3524@localhost (orig r2453): bruno | 2009-10-07 10:17:03 +0200

  • Fix a bug in handling of -E option with real devices (bad report in function mr_make_devlist_from_pathlist of the test between -E and -I)


r3525@localhost (orig r2454): bruno | 2009-10-07 10:19:02 +0200

  • Fix an error in the test for grub conf files (or used instead of and)


r3526@localhost (orig r2455): bruno | 2009-10-07 16:14:59 +0200
afio is under /bin on Debian


r3527@localhost (orig r2456): bruno | 2009-10-07 17:31:26 +0200

  • Adds support for libcrc32c (needed by bnx2x)


r3532@localhost (orig r2457): bruno | 2009-10-09 13:33:44 +0200

  • Apply path from Matthew Cline (matt_at_nightrealms.com) in order to fix #359


r3533@localhost (orig r2458): bruno | 2009-10-09 13:41:02 +0200
Adds a conf file example for mindi and fix #360


r3535@localhost (orig r2459): bruno | 2009-10-09 15:13:01 +0200
MOde of conf file


r3546@localhost (orig r2461): bruno | 2009-10-14 01:12:24 +0200

  • umount freshly created VFAT partition on USB key as Ubunu has an automounter mounting it as soon as created (Steffen Neumann sneumann_at_ipb-halle.de)


r3566@localhost (orig r2463): bruno | 2009-10-26 01:34:16 +0100

  • Reset an error counter before blanking a DVD to avoid always returning an error (Vincent Raman vincent.raman_at_macqel.eu)


r3567@localhost (orig r2464): bruno | 2009-10-26 13:57:14 +0100
bzip2 is under /bin on Debian


r3568@localhost (orig r2465): bruno | 2009-10-28 01:46:30 +0100
some distro hold lvm commands under /usr/sbin


r3595@localhost (orig r2469): bruno | 2009-11-10 12:22:10 +0100
/dev/shm is now part of the default exclude list


r3596@localhost (orig r2470): bruno | 2009-11-10 12:32:40 +0100
Remove useless pb_log and MONDO_TRACEFILE


r3597@localhost (orig r2471): bruno | 2009-11-10 12:57:58 +0100
Improve analysis of kernel modules by printing whether it's a live or extra module which has not been found (Matthew Cline) as reported in #362


r3598@localhost (orig r2472): bruno | 2009-11-10 13:21:46 +0100

  • Default to DVD size when in iso or netfs mode


r3599@localhost (orig r2473): bruno | 2009-11-10 14:13:10 +0100

  • Fix #363 where exclude_paths was extended up to memory limit dumping core


r3600@localhost (orig r2474): bruno | 2009-11-10 14:31:14 +0100

  • Update deplist for Debian support


r3602@localhost (orig r2476): bruno | 2009-11-11 02:44:42 +0100

  • small improvement for loging in USB case


r3603@localhost (orig r2477): bruno | 2009-11-11 13:29:27 +0100

  • Adds a nolvm boot option at restore time


r3604@localhost (orig r2478): bruno | 2009-11-11 19:54:51 +0100

  • Fix #367 - the for loop doesn't make any test now, as it was computed before entering the loop, leading to an error, and was also made inside the loop anyway.


r3605@localhost (orig r2479): bruno | 2009-11-12 00:32:45 +0100

  • Add support for diskdumplib driver useful for RHEL 3 and IBM xseries 336


r3606@localhost (orig r2480): bruno | 2009-11-12 01:09:40 +0100

  • If using nolvm, mondorestore should also not nalyze and handle i-want-my-lvm


r3608@localhost (orig r2482): bruno | 2009-11-14 12:54:11 +0100
Fix bunzip2 on debian as well


r3610@localhost (orig r2484): bruno | 2009-11-15 00:44:19 +0100

  • Adds support for variable serial port console, with defalut to /dev/ttyS0, and a boot param to change it with serial=/dev/ttySx


r3615@localhost (orig r2485): bruno | 2009-11-15 01:34:33 +0100

r3614@localhost: bruno | 2009-11-15 01:34:12 +0100
Adds a space in exclude paths


r3623@localhost (orig r2487): bruno | 2009-11-18 20:41:40 +0100

r3620@localhost: bruno | 2009-11-18 10:31:36 +0100

  • Only link /dev/tty to serial port when there is indeed a serial port. If not breaks mondorestore on normal console


r3631@localhost (orig r2490): bruno | 2009-11-24 01:48:29 +0100
Put news below in the main page to make it more readable


r3648@localhost (orig r2492): bruno | 2009-11-25 23:50:13 +0100

r3647@localhost: bruno | 2009-11-25 23:49:11 +0100

  • Add warning for -f and SW Raid as in 2.2.10


r3650@localhost (orig r2493): bruno | 2009-11-26 00:19:52 +0100

r3649@localhost: bruno | 2009-11-26 00:18:27 +0100

  • Addition of the german translation made by Magnus Rasche (Magnus.rasche_at_gmx.de) and Website inclusion


r3652@localhost (orig r2495): bruno | 2009-11-27 15:55:55 +0100
cosmetic display fix
r3659@localhost (orig r2498): bruno | 2009-12-05 17:53:03 +0100
nfsopt restore boot time option added to support custom mount options for network restore


r3684@localhost (orig r2501): bruno | 2009-12-17 00:35:08 +0100
Fix #375 mondo will segfault if the partition in sensibly_set_tmpdir_and_scratchdir() is read-only (cylau)


r3685@localhost (orig r2502): bruno | 2009-12-17 01:02:47 +0100

  • Fix an issue in the function listing kernel modules when not found


r3686@localhost (orig r2503): bruno | 2009-12-17 01:15:01 +0100
Adds scsi_dump_register to mindi SCSI_MODS for RHEL3 + IBM servers


r3701@localhost (orig r2504): bruno | 2009-12-23 02:24:33 +0100

  • Addition of the Lab for Mondorescue


r3702@localhost (orig r2505): bruno | 2009-12-23 02:41:17 +0100
Web site update for Lab MondoRescue delivery


r3706@localhost (orig r2506): bruno | 2010-01-04 11:31:53 +0100

  • Fix a bug when isodir is / only when splitting it in iso_path and iso_mnt


r3707@localhost (orig r2507): bruno | 2010-01-04 13:22:49 +0100

  • Fix #377: Segfault in pause_and_ask_for_cdr() (ggeens)


  • Property svn:keywords set to Id
File size: 29.0 KB
Line 
1/* subroutines for handling mountlist
2 $Id: libmondo-mountlist.c 2508 2010-01-04 18:21:55Z bruno $
3*/
4
5
6/**
7 * @file
8 * Functions which manipulate the mountlist.
9 */
10
11#include "my-stuff.h"
12#include "mr_mem.h"
13#include "mondostructures.h"
14#include "libmondo-mountlist.h"
15#include "lib-common-externs.h"
16#include "libmondo-raid-EXT.h"
17#include "libmondo-devices-EXT.h"
18#include "libmondo-tools-EXT.h"
19#include "libmondo-string-EXT.h"
20#include "newt-specific-EXT.h"
21
22/*@unused@*/
23//static char cvsid[] = "$Id: libmondo-mountlist.c 2508 2010-01-04 18:21:55Z bruno $";
24
25/* Reference to global bkpinfo */
26extern struct s_bkpinfo *bkpinfo;
27
28/**
29 * @addtogroup mountlistGroup
30 * @{
31 */
32/**
33 * Evaluate a drive within the mountlist for flaws. For example, too many
34 * primary partitions, the first logical isn't 5, duplicate partitions,
35 * ovar-allocated or under-allocated, unsupported format, silly size, or
36 * silly mountpoint. Under FreeBSD, this checks the disklabel too, for the above-mentioned
37 * errors as well as too many BSD partitions (more than 'h').
38 * @param mountlist The mountlist to check.
39 * @param drive The drive to check (e.g. @c /dev/hda).
40 * @return The flaws string found (NULL for success) allocated to be freed
41 * @see evaluate_mountlist
42 */
43char *evaluate_drive_within_mountlist(struct mountlist_itself *mountlist, char *drive)
44#ifdef __FreeBSD__
45{
46// FreeBSD-specific version of evaluate_drive_within_mountlist()
47 /*@ int ************************************************************* */
48 int prev_part_no = 0;
49 int curr_part_no = 0;
50 int pos = 0, npos = 0;
51 int res = 0;
52 int mountpoint_copies = 0;
53 int device_copies = 0;
54 int i = 0;
55 int cur_sp_no = 0;
56 int prev_sp_no = 0;
57 int foundsome = FALSE;
58
59 /*@ buffers ******************************************************** */
60 char tmp = NULL;
61 char *device = NULL;
62
63 char *flaws_str = NULL;
64
65 /*@ long *********************************************************** */
66 long physical_drive_size = 0;
67 long amount_allocated = 0;
68
69 /*@ pointers ******************************************************* */
70 char *part_table_fmt;
71
72 /*@ initialize ***************************************************** */
73 prev_part_no = 0;
74 mr_asprintf(flaws_str, "%s", "");
75
76
77 physical_drive_size = get_phys_size_of_drive(drive);
78
79 if (physical_drive_size < 0) {
80 mr_asprintf(tmp, " %s does not exist.", drive);
81 mr_strcat(flaws_str, "%s", tmp);
82 } else {
83 mr_asprintf(tmp, "%s is %ld MB", drive, physical_drive_size);
84 }
85 log_it(tmp);
86 mr_free(tmp);
87
88
89 /* check DD */
90 for (cur_sp_no = 'a'; cur_sp_no < 'z'; ++cur_sp_no) {
91 mr_asprintf(device, "%s%c", drive, cur_sp_no);
92 if (find_device_in_mountlist(mountlist, device) >= 0) {
93 foundsome = TRUE;
94 }
95 mr_free(device);
96 }
97 if (foundsome) {
98 for (cur_sp_no = 'a'; cur_sp_no < 'z'; ++cur_sp_no) {
99 mr_asprintf(device, "%s%c", drive, cur_sp_no);
100 pos = find_device_in_mountlist(mountlist, device);
101 if (pos < 0) {
102 mr_free(device);
103 continue;
104 }
105 /* is it too big? */
106 if (curr_part_no > 'h') {
107 mr_asprintf(tmp, " Can only have up to 'h' in disklabel.");
108 log_it(tmp);
109 mr_strcat(flaws_str, tmp);
110 mr_free(tmp);
111 res++;
112 }
113 /* does partition /dev/adXsYZ exist more than once in the mountlist? */
114 for (i = 0, mountpoint_copies = 0, device_copies = 0;
115 i < mountlist->entries; i++) {
116 if (!strcmp(device, mountlist->el[i].device)) {
117 device_copies++;
118 }
119 }
120 if (device_copies > 1) {
121 mr_asprintf(tmp, " %s %s's.", number_to_text(device_copies), device);
122 if (!strstr(flaws_str, tmp)) {
123 log_it(tmp);
124 mr_strcat(flaws_str, tmp);
125 res++;
126 }
127 mr_free(tmp);
128 }
129 /* silly partition size? */
130 if (mountlist->el[pos].size < 8192
131 && strcmp(mountlist->el[pos].mountpoint, "lvm")) {
132 mr_asprintf(tmp, " %s is tiny!", device);
133 log_it(tmp);
134 mr_strcat(flaws_str, tmp);
135 mr_free(tmp);
136 res++;
137 }
138 /* mountpoint should begin with / unless it is swap, lvm or raid */
139 if (strcmp(mountlist->el[pos].mountpoint, "swap")
140 && strcmp(mountlist->el[pos].mountpoint, "lvm")
141 && strcmp(mountlist->el[pos].mountpoint, "raid")
142 && strcmp(mountlist->el[pos].mountpoint, "image")
143 && strcmp(mountlist->el[pos].mountpoint, "none")
144 && mountlist->el[pos].mountpoint[0] != '/') {
145 mr_asprintf(tmp, " %s has a weird mountpoint.", device);
146 log_it(tmp);
147 mr_strcat(flaws_str, tmp);
148 mr_free(tmp);
149 res++;
150 }
151 /* is format sensible? */
152 if (!is_this_a_valid_disk_format(mountlist->el[pos].format)) {
153 mr_asprintf(tmp, " %s has unsupported format %s.", device, mountlist->el[pos].format);
154 log_it(tmp);
155 mr_strcat(flaws_str, tmp);
156 mr_free(tmp);
157 res++;
158 }
159 mr_free(device);
160
161 amount_allocated += mountlist->el[pos].size / 1024L;
162 prev_sp_no = cur_sp_no;
163 }
164 }
165
166 npos = pos = 0;
167 for (curr_part_no = 1; curr_part_no < 99; curr_part_no++) {
168 device = build_partition_name(drive, curr_part_no);
169 pos = find_device_in_mountlist(mountlist, device);
170 npos = 0;
171 for (cur_sp_no = 'a'; cur_sp_no <= 'h'; cur_sp_no++) {
172 mr_asprintf(tmp, "%ss%i%c", device, curr_part_no, cur_sp_no);
173 if (find_device_in_mountlist(mountlist, tmp) >= 0) {
174 npos++;
175 }
176 mr_free(tmp);
177 }
178 mr_free(device);
179
180 if (((pos >= 0) || npos) && foundsome) {
181 mr_strcat(flaws_str, " %s has both DD and PC-style partitions.", drive);
182 return(flaws_str); // fatal error
183 }
184
185 device = build_partition_name(drive, curr_part_no);
186 if (pos > 0 && !npos) {
187 /* gap in the partition list? */
188 if (curr_part_no - prev_part_no > 1) {
189 if (prev_part_no == 0) {
190 mr_asprintf(tmp, " Gap prior to %s.", device);
191 log_it(tmp);
192 mr_strcat(flaws_str, "%s", tmp);
193 mr_free(tmp);
194 res++;
195 } else if (curr_part_no > 5
196 || (curr_part_no <= 4 && prev_part_no > 0)) {
197 mr_asprintf(tmp, " Gap between %ss%d and %d.", drive, prev_part_no, curr_part_no);
198 log_it(tmp);
199 mr_strcat(flaws_str, "%s", tmp);
200 mr_free(tmp);
201 res++;
202 }
203 }
204 /* GPT allows more than 4 primary partitions */
205 part_table_fmt = which_partition_format(drive);
206 /* no spare primary partitions to help accommodate the logical(s)? */
207 if ((curr_part_no >= 5 && prev_part_no == 4)
208 && (strcmp(part_table_fmt, "MBR") == 0)) {
209 mr_asprintf(tmp, " Partition %ss4 is occupied.", drive);
210 log_it(tmp);
211 mr_strcat(flaws_str, "%s", tmp);
212 mr_free(tmp);
213 res++;
214 }
215 /* does partition /dev/adXsY exist more than once in the mountlist? */
216 for (i = 0, mountpoint_copies = 0, device_copies = 0;
217 i < mountlist->entries; i++) {
218 if (!strcmp(device, mountlist->el[i].device)) {
219 device_copies++;
220 }
221 }
222 if (device_copies > 1) {
223 mr_asprintf(tmp, " %s %s's.", number_to_text(device_copies), device);
224 if (!strstr(flaws_str, "%s", tmp)) {
225 log_it(tmp);
226 mr_strcat(flaws_str, "%s", tmp);
227 res++;
228 }
229 mr_free(tmp);
230 }
231 /* silly partition size? */
232 if (mountlist->el[pos].size < 8192
233 && strcmp(mountlist->el[pos].mountpoint, "lvm")) {
234 mr_asprintf(tmp, " %s is tiny!", device);
235 log_it(tmp);
236 mr_strcat(flaws_str, "%s", tmp);
237 mr_free(tmp);
238 res++;
239 }
240 /* mountpoint should begin with / unless it is swap, lvm or raid */
241 if (strcmp(mountlist->el[pos].mountpoint, "swap")
242 && strcmp(mountlist->el[pos].mountpoint, "lvm")
243 && strcmp(mountlist->el[pos].mountpoint, "raid")
244 && strcmp(mountlist->el[pos].mountpoint, "image")
245 && strcmp(mountlist->el[pos].mountpoint, "none")
246 && mountlist->el[pos].mountpoint[0] != '/') {
247 mr_asprintf(tmp, " %s has a weird mountpoint.", device);
248 log_it(tmp);
249 mr_strcat(flaws_str, "%s", tmp);
250 mr_free(tmp);
251 res++;
252 }
253 /* is format sensible? */
254 if (!is_this_a_valid_disk_format(mountlist->el[pos].format)) {
255 mr_asprintf(tmp, " %s has unsupported format %s.", device, mountlist->el[pos].format);
256 log_it(tmp);
257 mr_strcat(flaws_str, "%s", tmp);
258 mr_free(tmp);
259 res++;
260 }
261 } else {
262 /* Check subpartitions */
263 for (cur_sp_no = 'a'; cur_sp_no < 'z'; ++cur_sp_no) {
264 mr_free(device);
265 mr_asprintf(device, "%ss%d%c", drive, curr_part_no, cur_sp_no);
266 pos = find_device_in_mountlist(mountlist, device);
267 if (pos < 0) {
268 continue;
269 }
270 /* is it too big? */
271 if (curr_part_no > 'h') {
272 mr_asprintf(tmp, " Can only have up to 'h' in disklabel.");
273 log_it(tmp);
274 mr_strcat(flaws_str, "%s", tmp);
275 mr_free(tmp);
276 res++;
277 }
278 /* does partition /dev/adXsYZ exist more than once in the mountlist? */
279 for (i = 0, mountpoint_copies = 0, device_copies = 0;
280 i < mountlist->entries; i++) {
281 if (!strcmp(device, mountlist->el[i].device)) {
282 device_copies++;
283 }
284 }
285 if (device_copies > 1) {
286 mr_asprintf(tmp, " %s %s's.", number_to_text(device_copies), device);
287 if (!strstr(flaws_str, tmp)) {
288 log_it(tmp);
289 mr_strcat(flaws_str, "%s", tmp);
290 res++;
291 }
292 mr_free(tmp);
293 }
294 /* silly partition size? */
295 if (mountlist->el[pos].size < 8192
296 && strcmp(mountlist->el[pos].mountpoint, "lvm")) {
297 mr_asprintf(tmp, " %s is tiny!", device);
298 log_it(tmp);
299 mr_strcat(flaws_str, "%s", tmp);
300 mr_free(tmp);
301 res++;
302 }
303 /* mountpoint should begin with / unless it is swap, lvm or raid */
304 if (strcmp(mountlist->el[pos].mountpoint, "swap")
305 && strcmp(mountlist->el[pos].mountpoint, "lvm")
306 && strcmp(mountlist->el[pos].mountpoint, "raid")
307 && strcmp(mountlist->el[pos].mountpoint, "image")
308 && strcmp(mountlist->el[pos].mountpoint, "none")
309 && mountlist->el[pos].mountpoint[0] != '/') {
310 mr_asprintf(tmp, " %s has a weird mountpoint.", device);
311 log_it(tmp);
312 mr_strcat(flaws_str, "%s", tmp);
313 mr_free(tmp);
314 res++;
315 }
316 /* is format sensible? */
317 if (!is_this_a_valid_disk_format
318 (mountlist->el[pos].format)) {
319 mr_asprintf(tmp, " %s has unsupported format %s.", device, mountlist->el[pos].format);
320 log_it(tmp);
321 mr_strcat(flaws_str, "%s", tmp);
322 mr_free(tmp);
323 res++;
324 }
325 amount_allocated += mountlist->el[pos].size / 1024L;
326 prev_sp_no = cur_sp_no;
327 }
328 }
329 mr_free(device);
330
331 /* OK, continue with main loop */
332 amount_allocated += mountlist->el[pos].size / 1024L;
333 prev_part_no = curr_part_no;
334 }
335
336 /* Over-allocated the disk? Unallocated space on disk? */
337 if (amount_allocated > physical_drive_size) // Used to be +1, but what if you're 1 MB too high?
338 {
339 mr_asprintf(tmp, " %ld MB over-allocated on %s.", amount_allocated - physical_drive_size, drive);
340 log_it(tmp);
341 mr_strcat(flaws_str, "%s", tmp);
342 mr_free(tmp);
343 res++;
344 } else if (amount_allocated < physical_drive_size - 1) { /* NOT AN ERROR, JUST A WARNING :-) */
345 mr_asprintf(tmp, " %ld MB unallocated on %s.", physical_drive_size - amount_allocated, drive);
346 log_it(tmp);
347 mr_strcat(flaws_str, "%s", tmp);
348 mr_free(tmp);
349 }
350 if (res) {
351 return (NULL);
352 } else {
353 return (flaws_str);
354 }
355}
356
357#else
358// Linux-specific version of evaluate_drive_within_mountlist()
359{
360
361 /*@ int ************************************************************* */
362 int prev_part_no = 0;
363 int curr_part_no = 0;
364 int pos = 0;
365 int res = 0;
366 int mountpoint_copies = 0;
367 int device_copies = 0;
368 int i = 0;
369
370 /*@ buffers ******************************************************** */
371 char *tmp = NULL;
372 char *device = NULL;
373 char *flaws_str = NULL;
374
375 /*@ long *********************************************************** */
376 long physical_drive_size = 0L;
377 long amount_allocated = 0L;
378
379 /*@ pointers ******************************************************* */
380 char *part_table_fmt = NULL;
381
382 /*@ initialize ***************************************************** */
383 assert_string_is_neither_NULL_nor_zerolength(drive);
384 assert(mountlist != NULL);
385 mr_asprintf(flaws_str, "%s", "");
386
387 prev_part_no = 0;
388
389 physical_drive_size = get_phys_size_of_drive(drive);
390
391 if (physical_drive_size < 0) {
392 mr_asprintf(tmp, " %s does not exist.", drive);
393 log_it(tmp);
394 log_it(tmp);
395 mr_strcat(flaws_str, "%s", tmp);
396 res++;
397 mr_free(tmp);
398 return(flaws_str);
399 } else {
400 log_it("%s is %ld MB", drive, physical_drive_size);
401 }
402
403 for (curr_part_no = 1; curr_part_no < 99; curr_part_no++) {
404 device = build_partition_name(drive, curr_part_no);
405 pos = find_device_in_mountlist(mountlist, device);
406 if (pos < 0) {
407 continue;
408 }
409 log_msg(2, "Processing partition %s on %s #%d in mountlist", device, drive, pos);
410 /* gap in the partition list? */
411 if (curr_part_no - prev_part_no > 1) {
412 if (prev_part_no == 0) {
413 mr_asprintf(tmp, " Gap prior to %s.", device);
414 log_it(tmp);
415 mr_strcat(flaws_str, "%s", tmp);
416 mr_free(tmp);
417 res++;
418 } else if (curr_part_no > 5
419 || (curr_part_no <= 4 && prev_part_no > 0)) {
420 mr_asprintf(tmp, " Gap on %s between %d and %d.", drive, prev_part_no, curr_part_no);
421 log_it(tmp);
422 mr_strcat(flaws_str, "%s", tmp);
423 mr_free(tmp);
424 res++;
425 }
426 }
427 /* GPT allows more than 4 primary partitions */
428 part_table_fmt = which_partition_format(drive);
429 /* no spare primary partitions to help accommodate the logical(s)? */
430 if ((curr_part_no >= 5 && prev_part_no == 4) && (strcmp(part_table_fmt, "MBR") == 0)) {
431 mr_asprintf(tmp, " Partition 4 of %s is occupied.", drive);
432 log_it(tmp);
433 mr_strcat(flaws_str, "%s", tmp);
434 mr_free(tmp);
435 res++;
436 }
437 mr_free(part_table_fmt);
438
439 /* does partition /dev/hdNX exist more than once in the mountlist? */
440 for (i = 0, mountpoint_copies = 0, device_copies = 0;
441 i < mountlist->entries; i++) {
442 if (!strcmp(device, mountlist->el[i].device)) {
443 device_copies++;
444 }
445 }
446 if (device_copies > 1) {
447 mr_asprintf(tmp, " %s %s's.", number_to_text(device_copies), device);
448 if (!strstr(flaws_str, tmp)) {
449 log_it(tmp);
450 mr_strcat(flaws_str, "%s", tmp);
451 res++;
452 }
453 mr_free(tmp);
454 }
455 /* silly partition size? */
456 if (mountlist->el[pos].size < 8192
457 && strcmp(mountlist->el[pos].mountpoint, "lvm")) {
458 mr_asprintf(tmp, " %s is tiny!", device);
459 log_it(tmp);
460 mr_strcat(flaws_str, "%s", tmp);
461 mr_free(tmp);
462 res++;
463 }
464 /* mountpoint should begin with / unless it is swap, lvm or raid */
465 if (strcmp(mountlist->el[pos].mountpoint, "swap")
466 && strcmp(mountlist->el[pos].mountpoint, "lvm")
467 && strcmp(mountlist->el[pos].mountpoint, "raid")
468 && strcmp(mountlist->el[pos].mountpoint, "image")
469 && mountlist->el[pos].mountpoint[0] != '/') {
470 mr_asprintf(tmp, " %s has a weird mountpoint.", device);
471 log_it(tmp);
472 mr_strcat(flaws_str, "%s", tmp);
473 mr_free(tmp);
474 res++;
475 }
476 /* is format sensible? */
477 if (!is_this_a_valid_disk_format(mountlist->el[pos].format)) {
478 mr_asprintf(tmp, " %s has unsupported format %s.", device, mountlist->el[pos].format);
479 log_it(tmp);
480 mr_strcat(flaws_str, "%s", tmp);
481 mr_free(tmp);
482 res++;
483 }
484 /* OK, continue with main loop */
485 amount_allocated += mountlist->el[pos].size / 1024L;
486 prev_part_no = curr_part_no;
487 mr_free(device);
488 }
489
490 /* Over-allocated the disk? Unallocated space on disk? */
491 if (amount_allocated > physical_drive_size + 1) {
492 mr_asprintf(tmp, " %ld MB over-allocated on %s.", amount_allocated - physical_drive_size, drive);
493 log_it(tmp);
494 mr_strcat(flaws_str, "%s", tmp);
495 mr_free(tmp);
496 res++;
497 } else if (amount_allocated < physical_drive_size - 1) { /* NOT AN ERROR, JUST A WARNING :-) */
498 mr_asprintf(tmp, " %ld MB unallocated on %s.", physical_drive_size - amount_allocated, drive);
499 log_it(tmp);
500 mr_strcat(flaws_str, "%s", tmp);
501 mr_free(tmp);
502 }
503
504 if (res == 0) {
505 mr_free(flaws_str);
506 log_msg(2, "Fine, no error in evaluate_drive_within_mountlist");
507 return (NULL);
508 } else {
509 log_msg(2, "Error in evaluate_drive_within_mountlist: %s", flaws_str);
510 return (flaws_str);
511 }
512}
513#endif
514
515
516/**
517 * Evaluate a whole mountlist for flaws. Calls evaluate_drive_within_mountlist()
518 * for each drive, and then spreads the flaws across three lines.
519 * @param mountlist The mountlist to evaluate.
520 * @return The flaws string (NULL for success).
521 * @see evaluate_drive_within_mountlist
522 */
523char *evaluate_mountlist(struct mountlist_itself *mountlist) {
524
525 /*@ buffer *********************************************************** */
526 struct list_of_disks *drivelist;
527 char *tmp = NULL;
528 char *flaws_str = NULL;
529
530 int currline = 0;
531 int copies = 0;
532 int last_copy = 0;
533
534 /*@ buffetr ********************************************************* */
535 char *curr_mountpoint = NULL;
536
537 /*@ int ************************************************************** */
538 int i = 0;
539
540 /*@ initialize ******************************************************* */
541
542 drivelist = malloc(sizeof(struct list_of_disks));
543 assert(mountlist != NULL);
544
545 make_list_of_drives_in_mountlist(mountlist, drivelist);
546
547 log_it("Evaluating mountlist...");
548
549 for (i = 0; i < drivelist->entries; i++) {
550 if (strstr
551 (drivelist->el[i].device,
552 DONT_KNOW_HOW_TO_EVALUATE_THIS_DEVICE_TYPE)) {
553 log_it(" Not evaluating %s (I don't know how yet)", drivelist->el[i].device);
554 } else {
555 log_msg(8, "Evaluating drive #%d (%s) within mountlist", i, drivelist->el[i].device);
556 tmp = evaluate_drive_within_mountlist(mountlist, drivelist->el[i].device);
557 }
558 log_msg(8,"Entry: %d (%s)", i, drivelist->el[i].device);
559 /* BCO: tmp can be NULL */
560 if (tmp != NULL) {
561 log_msg(8,"Adding: %s to flaws_str", tmp);
562 mr_strcat(flaws_str, "%s", tmp);
563 mr_free(tmp);
564 }
565 }
566
567 /* Look for duplicate mountpoints in mountlist. */
568
569 for (currline = 0; currline < mountlist->entries; currline++) {
570 mr_asprintf(curr_mountpoint, "%s", mountlist->el[currline].mountpoint);
571 for (i = 0, copies = 0, last_copy = -1; i < mountlist->entries; i++) {
572 if (!strcmp(mountlist->el[i].mountpoint, curr_mountpoint)
573 && strcmp(mountlist->el[i].mountpoint, "lvm")
574 && strcmp(mountlist->el[i].mountpoint, "swap")) {
575 last_copy = i;
576 copies++;
577 }
578 }
579 if (copies > 1 && last_copy == currline
580 && strcmp(curr_mountpoint, "raid")) {
581 mr_asprintf(tmp, " %s %s's.", number_to_text(copies), curr_mountpoint);
582 mr_strcat(flaws_str, "%s", tmp);
583 log_msg(8,"Adding: %s to flaws_str", tmp);
584 mr_free(tmp);
585 }
586 mr_free(curr_mountpoint);
587 }
588
589 return(flaws_str);
590}
591
592
593/**
594 * Find the index number of @p device in the mountlist.
595 * The device given must match @p mountlist->el[N].device exactly, case-sensitive.
596 * @param mountlist The mountlist to search in.
597 * @param device The device to search for.
598 * @return The zero-based index of the device, or -1 if it could not be found.
599 */
600int
601find_device_in_mountlist(struct mountlist_itself *mountlist, char *device)
602{
603
604 /*@ int ************************************************************** */
605 int i = 0;
606
607 assert(mountlist != NULL);
608 assert_string_is_neither_NULL_nor_zerolength(device);
609 for (i = 0;
610 i < mountlist->entries
611 && strcmp(mountlist->el[i].device, device) != 0; i++);
612
613 if (i == mountlist->entries) {
614 return (-1);
615 } else {
616 return (i);
617 }
618}
619
620
621/**
622 * Make a list of the drives mentioned in the mountlist.
623 * @param mountlist The mountlist to examine.
624 * @param drivelist Where to put the list of drives found.
625 * @return The number of physical (non-RAID non-LVM) drives found, or \<= 0 for error.
626 */
627int
628make_list_of_drives_in_mountlist(struct mountlist_itself *mountlist,
629 struct list_of_disks *drivelist)
630{
631
632 /*@ int ************************************************************* */
633 int lino;
634 int noof_drives;
635 int j;
636
637 /*@ buffers ********************************************************* */
638 char *drive = NULL;
639 char *truncdrive = NULL;
640
641 long long size;
642
643 assert(mountlist != NULL);
644 assert(drivelist != NULL);
645 log_it("Making list of drives");
646 for (lino = 0, noof_drives = 0; lino < mountlist->entries; lino++) {
647
648 mr_asprintf(drive, "%s", mountlist->el[lino].device);
649 if (!strncmp(drive, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) {
650 log_msg(8, "Not putting %s in list of drives: it's a virtual drive", drive);
651 mr_free(drive);
652 continue;
653 }
654
655 size = mountlist->el[lino].size;
656 if (size == 0) {
657 log_msg(8, "Not putting %s in list of drives: it has zero size (maybe an LVM volume)", drive);
658 mr_free(drive);
659 continue;
660 }
661
662 log_msg(8, "Putting %s with size %lli in list of drives", drive, size);
663
664 /* memory allocation */
665 truncdrive = truncate_to_drive_name(drive);
666 mr_free(drive);
667
668 log_msg(8, "drive truncated to %s", truncdrive);
669
670 for (j = 0;
671 j < noof_drives
672 && strcmp(drivelist->el[j].device, truncdrive) != 0; j++) {
673 continue;
674 }
675 if (j == noof_drives) {
676 strncpy(drivelist->el[noof_drives].device, truncdrive, 63);
677 drivelist->el[noof_drives].device[63] = '\0';
678 log_msg(8,"Adding drive %s to list", drivelist->el[noof_drives].device);
679 noof_drives++;
680 }
681 paranoid_free(truncdrive);
682 if (noof_drives >= MAXIMUM_DISKS_PER_RAID_DEV) {
683 log_msg(0, "Unable to handle mountlist with more than %d lines", MAXIMUM_DISKS_PER_RAID_DEV);
684 log_to_screen("Unable to handle a so big mountlist");
685 finish(1);
686 }
687 }
688 drivelist->entries = noof_drives;
689 log_msg(8, "Made list of %d drives",noof_drives);
690
691 return (noof_drives);
692}
693
694
695/**
696 * Make a list of RAID partitions not currently associated with any RAID device.
697 * The user may add any of these partitions to the RAID device.
698 * @param output_list Where to put the list of unallocated RAID partitions.
699 * @param mountlist The mountlist to examine.
700 * @param raidlist The raidlist to examine.
701 */
702void make_list_of_unallocated_raid_partitions(struct mountlist_itself
703 *output_list,
704 struct mountlist_itself
705 *mountlist,
706 struct raidlist_itself
707 *raidlist)
708{
709
710 /*@ int ************************************************************* */
711 int items = 0;
712 int i = 0;
713 int used_by = 0;
714
715 assert(output_list != NULL);
716 assert(mountlist != NULL);
717 assert(raidlist != NULL);
718 log_it("MLOURP -- starting");
719 items = 0;
720
721
722 for (i = 0; i < mountlist->entries; i++) {
723 if (strstr(mountlist->el[i].mountpoint, "raid")) {
724 used_by = which_raid_device_is_using_this_partition(raidlist,
725 mountlist->el[i].
726 device);
727 if (used_by < 0) {
728 memcpy((void *) &output_list->el[items++],
729 (void *) &mountlist->el[i],
730 sizeof(struct mountlist_line));
731 log_it("%s is available; user may choose to add it to raid device", output_list->el[items - 1].device);
732 }
733 }
734 }
735 output_list->entries = items;
736 log_it("MLUORP -- ending");
737}
738
739
740/**
741 * Get the size of a mountlist entry by the @c device field.
742 * @param mountlist The mountlist to search in.
743 * @param device The device to search for
744 * @return The size of the device (in KB), or -1 if it could not be found.
745 */
746long long
747size_of_specific_device_in_mountlist(struct mountlist_itself *mountlist,
748 char *device)
749{
750 /*@ int ************************************************************** */
751 int i = 0;
752
753
754 assert(mountlist != NULL);
755 assert_string_is_neither_NULL_nor_zerolength(device);
756
757 for (i = 0;
758 i < mountlist->entries && strcmp(mountlist->el[i].device, device);
759 i++);
760 if (i == mountlist->entries) {
761 return (-1);
762 } else {
763 return (mountlist->el[i].size);
764 }
765}
766
767
768/**
769 * Load a file on disk into @p mountlist.
770 * The file on disk should consist of multiple lines, each containing 4 or 5
771 * columns: the device, the mountpoint, the filesystem type, the size in kilobytes, and optionally the filesystem label.
772 * Comments begin with a '#' without any leading whitespace. Any duplicate
773 * entries are renamed.
774 * @param mountlist The mountlist to load into.
775 * @param fname The name of the file to load the mountlist from.
776 * @return 0 for success, 1 for failure.
777 */
778int load_mountlist(struct mountlist_itself *mountlist, char *fname)
779{
780 FILE *fin = NULL;
781 /* malloc ** */
782 char *incoming = NULL;
783 char *siz = NULL;
784 char *tmp = NULL;
785 char *p = NULL;
786
787 int items = 0;
788 int j = 0;
789 int res = 0;
790
791 assert(mountlist != NULL);
792 assert_string_is_neither_NULL_nor_zerolength(fname);
793
794 if (!(fin = fopen(fname, "r"))) {
795 log_it("Unable to open mountlist - '%s'", fname);
796 log_to_screen("Cannot open mountlist");
797 return (1);
798 }
799 malloc_string(siz);
800 log_it("Loading mountlist...");
801 mr_getline(incoming, fin);
802 while (!feof(fin)) {
803#if linux
804 res = sscanf(incoming, "%s %s %s %s %s", mountlist->el[items].device, mountlist->el[items].mountpoint, mountlist->el[items].format, siz, mountlist->el[items].label);
805 if (res < 5) {
806 /* no label found */
807 log_msg(4, "no label found for %s",mountlist->el[items].device);
808 strcpy(mountlist->el[items].label,"");
809 }
810#elif __FreeBSD__
811 res = sscanf(incoming, "%s %s %s %s", mountlist->el[items].device, mountlist->el[items].mountpoint, mountlist->el[items].format, siz);
812 strcpy(mountlist->el[items].label,"");
813#endif
814
815 if (!strcmp(mountlist->el[items].device, "/proc") ||
816 !strcmp(mountlist->el[items].device, "proc") ||
817 !strcmp(mountlist->el[items].device, "/sys") ||
818 !strcmp(mountlist->el[items].device, "sys") ||
819 !strcmp(mountlist->el[items].device, "/devpts") ||
820 !strcmp(mountlist->el[items].device, "devpts")
821 ) {
822 log_msg(1, "Ignoring %s in mountlist - not loading that line :) ", mountlist->el[items].device);
823 mr_free(incoming);
824 mr_getline(incoming, fin);
825 continue;
826 }
827 mountlist->el[items].size = atoll(siz);
828 if (mountlist->el[items].device[0] != '\0'
829 && mountlist->el[items].device[0] != '#') {
830 for (j = 0;
831 j < items
832 && strcmp(mountlist->el[j].device,
833 mountlist->el[items].device); j++);
834 if (j < items) {
835 strcat(mountlist->el[items].device, "_dup");
836 log_it("Duplicate entry in mountlist - renaming to %s", mountlist->el[items].device);
837 }
838 mr_asprintf(tmp, "%s", mountlist->el[items].device);
839 if (strstr(tmp, "/dev/md/")) {
840 log_it("format_device() --- Contracting %s", tmp);
841 p = strrchr(tmp, '/');
842 if (p) {
843 *p = *(p + 1);
844 *(p + 1) = *(p + 2);
845 *(p + 2) = *(p + 3);
846 }
847 log_it("It was %s; it is now %s", mountlist->el[items].device, tmp);
848 strcpy(mountlist->el[items].device, tmp);
849 }
850 paranoid_free(tmp);
851
852 log_it("%s %s %s %lld %s", mountlist->el[items].device, mountlist->el[items].mountpoint, mountlist->el[items].format, mountlist->el[items].size, mountlist->el[items].label);
853 items++;
854 if (items >= MAX_MOUNTLIST_ENTRIES) {
855 log_to_screen("Too many lines in mountlist.. ABORTING");
856 finish(1);
857 }
858 }
859 mr_free(incoming);
860 mr_getline(incoming, fin);
861 }
862 mr_free(incoming);
863 paranoid_fclose(fin);
864 mountlist->entries = items;
865
866 log_it("Mountlist loaded successfully.");
867 log_it("%d entries in mountlist", items);
868
869 paranoid_free(siz);
870 return (0);
871}
872
873
874
875/**
876 * Save @p mountlist to a file on disk.
877 * @param mountlist The mountlist to save.
878 * @param fname The file to save it to.
879 * @return 0 for success, 1 for failure.
880 * @see load_mountlist
881 */
882int save_mountlist_to_disk(struct mountlist_itself *mountlist, char *fname)
883{
884 FILE *fout;
885 int i;
886
887 assert(mountlist != NULL);
888 assert_string_is_neither_NULL_nor_zerolength(fname);
889
890 log_it("save_mountlist_to_disk() --- saving to %s", fname);
891 if (!(fout = fopen(fname, "w"))) {
892 log_OS_error("WMTD - Cannot openout mountlist");
893 return (1);
894 }
895 for (i = 0; i < mountlist->entries; i++) {
896 fprintf(fout,
897 "%-15s %-15s %-15s %-15lld %-15s\n",
898 mountlist->el[i].device, mountlist->el[i].mountpoint,
899 mountlist->el[i].format, mountlist->el[i].size,
900 mountlist->el[i].label);
901 }
902 paranoid_fclose(fout);
903 return (0);
904}
905
906
907/**
908 * Sort the mountlist alphabetically by device.
909 * The sorting is done in-place.
910 * @param mountlist The mountlist to sort.
911 */
912void sort_mountlist_by_device(struct mountlist_itself *mountlist)
913{
914 int diff;
915 int lino = -999;
916
917 assert(mountlist != NULL);
918
919 while (lino < mountlist->entries) {
920 for (lino = 1; lino < mountlist->entries; lino++) {
921 diff =
922 strcmp_inc_numbers(mountlist->el[lino - 1].device,
923 mountlist->el[lino].device);
924 if (diff > 0) {
925 swap_mountlist_entries(mountlist, lino - 1, lino);
926 break;
927 }
928 }
929 }
930}
931
932
933/**
934 * Sort the mountlist alphabetically by mountpoint.
935 * The sorting is done in-place.
936 * @param mountlist The mountlist to sort.
937 * @param reverse If TRUE, then do a reverse sort.
938 */
939void
940sort_mountlist_by_mountpoint(struct mountlist_itself *mountlist,
941 bool reverse)
942{
943 int diff;
944 int lino = -999;
945
946 assert(mountlist != NULL);
947
948 while (lino < mountlist->entries) {
949 for (lino = 1; lino < mountlist->entries; lino++) {
950 diff =
951 strcmp(mountlist->el[lino - 1].mountpoint,
952 mountlist->el[lino].mountpoint);
953 if ((diff > 0 && !reverse) || ((diff < 0 && reverse))) {
954 swap_mountlist_entries(mountlist, lino - 1, lino);
955 break;
956 }
957 }
958 }
959}
960
961
962/**
963 * Swap two entries in the mountlist in-place.
964 * @param mountlist The mountlist to swap the entries in.
965 * @param a The index number of the first entry.
966 * @param b The index number of the second entry.
967 */
968void
969swap_mountlist_entries(struct mountlist_itself *mountlist, int a, int b)
970{
971 /*@ mallocs *** */
972 char *device = NULL;
973 char *mountpoint = NULL;
974 char *format = NULL;
975
976 long long size;
977
978 assert(mountlist != NULL);
979 assert(a >= 0);
980 assert(b >= 0);
981
982 mr_asprintf(device, "%s", mountlist->el[a].device);
983 mr_asprintf(mountpoint, "%s", mountlist->el[a].mountpoint);
984 mr_asprintf(format, "%s", mountlist->el[a].format);
985
986 size = mountlist->el[a].size;
987
988 strcpy(mountlist->el[a].device, mountlist->el[b].device);
989 strcpy(mountlist->el[a].mountpoint, mountlist->el[b].mountpoint);
990 strcpy(mountlist->el[a].format, mountlist->el[b].format);
991
992 mountlist->el[a].size = mountlist->el[b].size;
993
994 strcpy(mountlist->el[b].device, device);
995 strcpy(mountlist->el[b].mountpoint, mountpoint);
996 strcpy(mountlist->el[b].format, format);
997
998 mountlist->el[b].size = size;
999 mr_free(device);
1000 mr_free(mountpoint);
1001 mr_free(format);
1002}
1003
1004/* @} - end of mountlistGroup */
Note: See TracBrowser for help on using the repository browser.