Changeset 3287 in MondoRescue


Ignore:
Timestamp:
May 3, 2014, 10:13:14 AM (10 years ago)
Author:
Bruno Cornec
Message:
  • mondo-prep is now better wrt memory management (fgets part not done yet)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.2/mondo/src/mondorestore/mondo-prep.c

    r3286 r3287  
    182182
    183183#ifdef __FreeBSD__
    184     return (0);
     184return (0);
    185185#endif
    186186
     
    419419
    420420#ifdef __FreeBSD__
    421     log_to_screen("I don't know how to extrapolate the mountlist on FreeBSD. Sorry.");
    422     return (1);
     421log_to_screen("I don't know how to extrapolate the mountlist on FreeBSD. Sorry.");
     422return (1);
    423423#endif
    424424
     
    439439             q = fgets(incoming, MAX_STR_LEN - 1, fin));
    440440        if (!feof(fin)) {
    441             log_it(tmp, "Investigating %s", old_mountlist->el[lino].device);
    442             for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL)
    443                  && !strstr(incoming, "raiddev");
    444                  q = fgets(incoming, MAX_STR_LEN - 1, fin)) {
    445                 if (strstr(incoming, OSSWAP("device", "drive"))
    446                     && !strchr(incoming, '#')) {
     441            log_it("Investigating %s", old_mountlist->el[lino].device);
     442            for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL) && !strstr(incoming, "raiddev"); q = fgets(incoming, MAX_STR_LEN - 1, fin)) {
     443                if (strstr(incoming, OSSWAP("device", "drive")) && !strchr(incoming, '#')) {
    447444                    for (p = incoming + strlen(incoming);
    448445                         *(p - 1) <= 32; p--);
    449446                    *p = '\0';
    450447                    for (p--; p > incoming && *(p - 1) > 32; p--);
    451                     log_it(tmp, "Extrapolating %s", p);
    452                     for (j = 0;
    453                          j < new_mountlist->entries
    454                          && strcmp(new_mountlist->el[j].device, p);
    455                          j++);
     448                    log_it("Extrapolating %s", p);
     449                    for (j = 0; j < new_mountlist->entries && strcmp(new_mountlist->el[j].device, p); j++);
    456450                    if (j >= new_mountlist->entries) {
    457451                        strcpy(new_mountlist-> el[new_mountlist->entries].device, p);
     
    461455                        new_mountlist->entries++;
    462456                    } else {
    463                         log_it(tmp, "Not adding %s to mountlist: it's already there", p);
     457                        log_it("Not adding %s to mountlist: it's already there", p);
    464458                    }
    465459                }
     
    639633/** int **************************************************************/
    640634#ifdef __FreeBSD__
    641     static bool vinum_started_yet = FALSE;
     635static bool vinum_started_yet = FALSE;
    642636#endif
    643637
     
    658652}
    659653#ifdef __FreeBSD__
    660     if (strcmp(format, "swap") == 0) {
    661         log_it("Not formatting %s - it's swap", device);
    662         return (0);
    663     }
     654if (strcmp(format, "swap") == 0) {
     655    log_it("Not formatting %s - it's swap", device);
     656    return (0);
     657}
    664658#endif
    665659if (strlen(format) <= 2) {
     
    675669    newtSuspend();
    676670#ifdef __FreeBSD__
    677     if (!vinum_started_yet) {
    678         if (!does_file_exist("/tmp/raidconf.txt")) {
    679             log_to_screen("/tmp/raidconf.txt does not exist. I therefore cannot start Vinum.");
    680         } else {
    681             int res;
    682             res = run_program_and_log_output("vinum create /tmp/raidconf.txt", TRUE);
    683             if (res) {
    684                 log_to_screen("`vinum create /tmp/raidconf.txt' returned errors. Please fix them and re-run mondorestore.");
    685                 finish(1);
     671if (!vinum_started_yet) {
     672    if (!does_file_exist("/tmp/raidconf.txt")) {
     673        log_to_screen("/tmp/raidconf.txt does not exist. I therefore cannot start Vinum.");
     674    } else {
     675        int res;
     676        res = run_program_and_log_output("vinum create /tmp/raidconf.txt", TRUE);
     677        if (res) {
     678            log_to_screen("`vinum create /tmp/raidconf.txt' returned errors. Please fix them and re-run mondorestore.");
     679            finish(1);
     680        }
     681        vinum_started_yet = TRUE;
     682    }
     683}
     684
     685if (vinum_started_yet) {
     686    FILE *fin;
     687    char line[MAX_STR_LEN];
     688
     689    log_to_screen(tmp, "Initializing Vinum device %s (this may take a *long* time)", device);
     690
     691    /* format raid partition */
     692    mr_asprintf(program, "for plex in `vinum lv -r %s | grep '^P' | tr '\t' ' ' | tr -s ' ' | cut -d' ' -f2`; do echo $plex; done > /tmp/plexes", basename(device));
     693    paranoid_system(program);
     694    if (g_fprep) {
     695        fprintf(g_fprep, "%s\n", program);
     696    }
     697    fin = fopen("/tmp/plexes", "r");
     698    while (fgets(line, MAX_STR_LEN - 1, fin)) {
     699        if (strchr(line, '\n'))
     700            *(strchr(line, '\n')) = '\0';   // get rid of the \n on the end
     701
     702        mr_asprintf(tmp, "Initializing plex: %s", line);
     703        open_evalcall_form(tmp);
     704        mr_free(tmp);
     705
     706        mr_asprintf(tmp, "vinum init %s", line);
     707        paranoid_system(tmp);
     708        mr_free(tmp);
     709
     710        while (1) {
     711            mr_asprintf(tmp, "vinum lp -r %s | grep '^S' | head -1 | tr -s ' ' | cut -d: -f2 | cut -f1 | sed 's/^ //' | sed 's/I //' | sed 's/%%//'", line);
     712            FILE *pin = popen(tmp, "r");
     713            mr_free(tmp);
     714
     715            char status[MAX_STR_LEN / 4];
     716            if (fgets(status, MAX_STR_LEN / 4 - 1, pin)) {
     717                // FIXME
    686718            }
    687             vinum_started_yet = TRUE;
    688         }
    689     }
    690 
    691     if (vinum_started_yet) {
    692         FILE *fin;
    693         char line[MAX_STR_LEN];
    694 
    695         log_to_screen(tmp, "Initializing Vinum device %s (this may take a *long* time)", device);
    696 
    697         /* format raid partition */
    698         mr_asprintf(program, "for plex in `vinum lv -r %s | grep '^P' | tr '\t' ' ' | tr -s ' ' | cut -d' ' -f2`; do echo $plex; done > /tmp/plexes", basename(device));
    699         paranoid_system(program);
    700         if (g_fprep) {
    701             fprintf(g_fprep, "%s\n", program);
    702         }
    703         fin = fopen("/tmp/plexes", "r");
    704         while (fgets(line, MAX_STR_LEN - 1, fin)) {
    705             if (strchr(line, '\n'))
    706                 *(strchr(line, '\n')) = '\0';   // get rid of the \n on the end
    707 
    708             mr_asprintf(tmp, "Initializing plex: %s", line);
    709             open_evalcall_form(tmp);
    710             mr_free(tmp);
    711 
    712             mr_asprintf(tmp, "vinum init %s", line);
    713             paranoid_system(tmp);
    714             mr_free(tmp);
    715 
    716             while (1) {
    717                 mr_asprintf(tmp, "vinum lp -r %s | grep '^S' | head -1 | tr -s ' ' | cut -d: -f2 | cut -f1 | sed 's/^ //' | sed 's/I //' | sed 's/%%//'", line);
    718                 FILE *pin = popen(tmp, "r");
    719                 mr_free(tmp);
    720 
    721                 char status[MAX_STR_LEN / 4];
    722                 if (fgets(status, MAX_STR_LEN / 4 - 1, pin)) {
    723                     // FIXME
    724                 }
    725                 pclose(pin);
    726 
    727                 if (!strcmp(status, "up")) {
    728                     break;  /* it's done */
    729                 }
    730                 update_evalcall_form(atoi(status));
    731                 usleep(250000);
     719            pclose(pin);
     720
     721            if (!strcmp(status, "up")) {
     722                break;  /* it's done */
    732723            }
    733             close_evalcall_form();
    734         }
    735         fclose(fin);
    736         unlink("/tmp/plexes");
    737     }
     724            update_evalcall_form(atoi(status));
     725            usleep(250000);
     726        }
     727        close_evalcall_form();
     728    }
     729    fclose(fin);
     730    unlink("/tmp/plexes");
     731}
    738732#else
    739     log_to_screen("Initializing RAID device %s", device);
    740 
    741     // Shouldn't be necessary.
    742     log_to_screen("Stopping %s", device);
    743     stop_raid_device(device);
     733log_to_screen("Initializing RAID device %s", device);
     734
     735// Shouldn't be necessary.
     736log_to_screen("Stopping %s", device);
     737stop_raid_device(device);
     738paranoid_system("sync");
     739sleep(1);
     740
     741log_msg(1, "Making %s", device);
     742// use mkraid if it exists, otherwise use mdadm
     743if (run_program_and_log_output("which mkraid", FALSE)) {
     744    res = create_raid_device_via_mdadm(raidlist, device, TRUE);
     745    log_msg(1, "Creating RAID device %s via mdadm returned %d", device, res);
     746} else {
     747    mr_asprintf(program, "mkraid --really-force %s", device);
     748    res = run_program_and_log_output(program, 1);
     749    log_msg(1, "%s returned %d", program, res);
    744750    paranoid_system("sync");
    745     sleep(1);
    746 
    747     log_msg(1, "Making %s", device);
    748     // use mkraid if it exists, otherwise use mdadm
    749     if (run_program_and_log_output("which mkraid", FALSE)) {
    750         res = create_raid_device_via_mdadm(raidlist, device, TRUE);
    751         log_msg(1, "Creating RAID device %s via mdadm returned %d", device, res);
    752     } else {
    753         mr_asprintf(program, "mkraid --really-force %s", device);
    754         res = run_program_and_log_output(program, 1);
    755         log_msg(1, "%s returned %d", program, res);
    756         paranoid_system("sync");
    757         sleep(3);
    758         start_raid_device(device);
    759         if (g_fprep) {
    760             fprintf(g_fprep, "%s\n", program);
    761         }
    762     }
    763     paranoid_system("sync");
    764     sleep(2);
    765 #endif
    766     paranoid_system("sync");
    767     sleep(1);
    768     newtResume();
     751    sleep(3);
     752    start_raid_device(device);
     753    if (g_fprep) {
     754        fprintf(g_fprep, "%s\n", program);
     755    }
     756}
     757paranoid_system("sync");
     758sleep(2);
     759#endif
     760paranoid_system("sync");
     761sleep(1);
     762newtResume();
    769763}
    770764
     
    800794    mr_free(program);
    801795#ifdef __FreeBSD__
    802         mr_asprintf(program, "newfs_msdos -F 32 %s", device);
     796    mr_asprintf(program, "newfs_msdos -F 32 %s", device);
    803797#else
    804798#ifdef __IA64__
    805         /* For EFI partitions take fat16
    806         * as we want to make small ones */
    807         mr_asprintf(program, "mkfs -t %s -F 16 %s", format, device);
     799    /* For EFI partitions take fat16
     800    * as we want to make small ones */
     801    mr_asprintf(program, "mkfs -t %s -F 16 %s", format, device);
    808802#else
    809         mr_asprintf(program, "mkfs -t %s -F 32 %s", format, device);
     803    mr_asprintf(program, "mkfs -t %s -F 32 %s", format, device);
    810804#endif
    811805#endif
     
    10071001 */
    10081002int make_dummy_partitions(FILE * pout_to_fdisk, char *drivename, int devno_we_must_allow_for) {
    1009     /** int **************************************************************/
    1010     int current_devno;
    1011     int previous_devno;
    1012     int retval = 0;
    1013     int res;
    1014 
    1015     /** buffers **********************************************************/
    1016     char *tmp;
    1017 
    1018     /** end **************************************************************/
    1019 
    1020     malloc_string(tmp);
    1021     assert_string_is_neither_NULL_nor_zerolength(drivename);
    1022 
    1023     if (devno_we_must_allow_for >= 5) {
    1024         sprintf(tmp, "Making dummy primary 1 on %s", drivename);
    1025         log_it(tmp);
    1026         g_maximum_progress++;
    1027         res =
    1028             partition_device(pout_to_fdisk, drivename, 1, 0, "ext2",
    1029                              32000);
    1030         retval += res;
    1031         previous_devno = 1;
    1032         current_devno = 5;
    1033     } else {
    1034         previous_devno = 0;
    1035         current_devno = 1;
    1036     }
    1037     for (; current_devno < devno_we_must_allow_for; current_devno++) {
    1038         sprintf(tmp, "Creating dummy partition %d on %s", current_devno, drivename);
    1039         log_it(tmp);
    1040         g_maximum_progress++;
    1041         res =
    1042             partition_device(pout_to_fdisk, drivename, current_devno,
    1043                              previous_devno, OSSWAP("ext2", "ufs"), 32000);
    1044         retval += res;
    1045         previous_devno = current_devno;
    1046     }
    1047     paranoid_free(tmp);
    1048     return (previous_devno);
     1003
     1004/** int **************************************************************/
     1005int current_devno;
     1006int previous_devno;
     1007int retval = 0;
     1008int res;
     1009
     1010assert_string_is_neither_NULL_nor_zerolength(drivename);
     1011
     1012if (devno_we_must_allow_for >= 5) {
     1013    log_it("Making dummy primary 1 on %s", drivename);
     1014    g_maximum_progress++;
     1015    res = partition_device(pout_to_fdisk, drivename, 1, 0, "ext2", 32000);
     1016    retval += res;
     1017    previous_devno = 1;
     1018    current_devno = 5;
     1019} else {
     1020    previous_devno = 0;
     1021    current_devno = 1;
     1022}
     1023for (; current_devno < devno_we_must_allow_for; current_devno++) {
     1024    log_it("Creating dummy partition %d on %s", current_devno, drivename);
     1025    g_maximum_progress++;
     1026    res = partition_device(pout_to_fdisk, drivename, current_devno, previous_devno, OSSWAP("ext2", "ufs"), 32000);
     1027    retval += res;
     1028    previous_devno = current_devno;
     1029}
     1030return (previous_devno);
    10491031}
    10501032
     
    10551037 * @return TRUE if it does, FALSE if it doesn't.
    10561038 */
    1057 bool mountlist_contains_raid_devices(struct mountlist_itself * mountlist)
    1058 {
    1059     /** int *************************************************************/
    1060     int i;
    1061     int matching = 0;
    1062 
    1063     /** end **************************************************************/
    1064 
    1065     assert(mountlist != NULL);
    1066 
    1067     for (i = 0; i < mountlist->entries; i++) {
    1068         if (strstr(mountlist->el[i].device, RAID_DEVICE_STUB)) {
    1069             matching++;
    1070         }
    1071     }
    1072     if (matching) {
    1073         return (TRUE);
    1074     } else {
    1075         return (FALSE);
    1076     }
     1039bool mountlist_contains_raid_devices(struct mountlist_itself * mountlist) {
     1040
     1041/** int *************************************************************/
     1042int i;
     1043int matching = 0;
     1044
     1045/** end **************************************************************/
     1046
     1047assert(mountlist != NULL);
     1048
     1049for (i = 0; i < mountlist->entries; i++) {
     1050    if (strstr(mountlist->el[i].device, RAID_DEVICE_STUB)) {
     1051        matching++;
     1052    }
     1053}
     1054if (matching) {
     1055    return (TRUE);
     1056} else {
     1057    return (FALSE);
     1058}
    10771059}
    10781060
    10791061/* The following 2 functions are stolen from /usr/src/sbin/disklabel/disklabel.c */
    10801062#ifdef __FreeBSD__
    1081 static void display_disklabel(FILE * f, const struct disklabel *lp)
    1082 {
    1083     int i, j;
    1084     const struct partition *pp;
    1085 
    1086     fprintf(f, "# %s\n", "Generated by Mondo Rescue");
    1087     if (lp->d_type < DKMAXTYPES)
    1088         fprintf(f, "type: %s\n", dktypenames[lp->d_type]);
    1089     else
    1090         fprintf(f, "type: %u\n", lp->d_type);
    1091     fprintf(f, "disk: %.*s\n", (int) sizeof(lp->d_typename),
    1092             lp->d_typename);
    1093     fprintf(f, "label: %.*s\n", (int) sizeof(lp->d_packname),
    1094             lp->d_packname);
    1095     fprintf(f, "flags:");
    1096     if (lp->d_flags & D_REMOVABLE)
    1097         fprintf(f, " removeable");
    1098     if (lp->d_flags & D_ECC)
    1099         fprintf(f, " ecc");
    1100     if (lp->d_flags & D_BADSECT)
    1101         fprintf(f, " badsect");
    1102     fprintf(f, "\n");
    1103     fprintf(f, "bytes/sector: %lu\n", (u_long) lp->d_secsize);
    1104     fprintf(f, "sectors/track: %lu\n", (u_long) lp->d_nsectors);
    1105     fprintf(f, "tracks/cylinder: %lu\n", (u_long) lp->d_ntracks);
    1106     fprintf(f, "sectors/cylinder: %lu\n", (u_long) lp->d_secpercyl);
    1107     fprintf(f, "cylinders: %lu\n", (u_long) lp->d_ncylinders);
    1108     fprintf(f, "sectors/unit: %lu\n", (u_long) lp->d_secperunit);
    1109     fprintf(f, "rpm: %u\n", lp->d_rpm);
    1110     fprintf(f, "interleave: %u\n", lp->d_interleave);
    1111     fprintf(f, "trackskew: %u\n", lp->d_trackskew);
    1112     fprintf(f, "cylinderskew: %u\n", lp->d_cylskew);
    1113     fprintf(f, "headswitch: %lu\t\t# milliseconds\n",
    1114             (u_long) lp->d_headswitch);
    1115     fprintf(f, "track-to-track seek: %ld\t# milliseconds\n",
    1116             (u_long) lp->d_trkseek);
    1117     fprintf(f, "drivedata: ");
    1118     for (i = NDDATA - 1; i >= 0; i--)
    1119         if (lp->d_drivedata[i])
     1063static void display_disklabel(FILE * f, const struct disklabel *lp) {
     1064
     1065int i, j;
     1066const struct partition *pp;
     1067
     1068fprintf(f, "# %s\n", "Generated by Mondo Rescue");
     1069if (lp->d_type < DKMAXTYPES)
     1070    fprintf(f, "type: %s\n", dktypenames[lp->d_type]);
     1071else
     1072    fprintf(f, "type: %u\n", lp->d_type);
     1073fprintf(f, "disk: %.*s\n", (int) sizeof(lp->d_typename), lp->d_typename);
     1074fprintf(f, "label: %.*s\n", (int) sizeof(lp->d_packname), lp->d_packname);
     1075fprintf(f, "flags:");
     1076if (lp->d_flags & D_REMOVABLE)
     1077    fprintf(f, " removeable");
     1078if (lp->d_flags & D_ECC)
     1079    fprintf(f, " ecc");
     1080if (lp->d_flags & D_BADSECT)
     1081    fprintf(f, " badsect");
     1082fprintf(f, "\n");
     1083fprintf(f, "bytes/sector: %lu\n", (u_long) lp->d_secsize);
     1084fprintf(f, "sectors/track: %lu\n", (u_long) lp->d_nsectors);
     1085fprintf(f, "tracks/cylinder: %lu\n", (u_long) lp->d_ntracks);
     1086fprintf(f, "sectors/cylinder: %lu\n", (u_long) lp->d_secpercyl);
     1087fprintf(f, "cylinders: %lu\n", (u_long) lp->d_ncylinders);
     1088fprintf(f, "sectors/unit: %lu\n", (u_long) lp->d_secperunit);
     1089fprintf(f, "rpm: %u\n", lp->d_rpm);
     1090fprintf(f, "interleave: %u\n", lp->d_interleave);
     1091fprintf(f, "trackskew: %u\n", lp->d_trackskew);
     1092fprintf(f, "cylinderskew: %u\n", lp->d_cylskew);
     1093fprintf(f, "headswitch: %lu\t\t# milliseconds\n", (u_long) lp->d_headswitch);
     1094fprintf(f, "track-to-track seek: %ld\t# milliseconds\n", (u_long) lp->d_trkseek);
     1095fprintf(f, "drivedata: ");
     1096for (i = NDDATA - 1; i >= 0; i--)
     1097    if (lp->d_drivedata[i])
     1098        break;
     1099if (i < 0)
     1100    i = 0;
     1101for (j = 0; j <= i; j++)
     1102    fprintf(f, "%lu ", (u_long) lp->d_drivedata[j]);
     1103fprintf(f, "\n\n%u partitions:\n", lp->d_npartitions);
     1104fprintf(f, "#         size   offset    fstype   [fsize bsize bps/cpg]\n");
     1105pp = lp->d_partitions;
     1106for (i = 0; i < lp->d_npartitions; i++, pp++) {
     1107    if (pp->p_size) {
     1108        fprintf(f, "    %c: %8lu %8lu  ", 'a' + i, (u_long) pp->p_size, (u_long) pp->p_offset);
     1109        if (pp->p_fstype < FSMAXTYPES)
     1110            fprintf(f, "%8.8s", fstypenames[pp->p_fstype]);
     1111        else
     1112            fprintf(f, "%8d", pp->p_fstype);
     1113        switch (pp->p_fstype) {
     1114
     1115        case FS_UNUSED: /* XXX */
     1116            fprintf(f, "      %5lu %5lu %5.5s ", (u_long) pp->p_fsize, (u_long) (pp->p_fsize * pp->p_frag), "");
    11201117            break;
    1121     if (i < 0)
    1122         i = 0;
    1123     for (j = 0; j <= i; j++)
    1124         fprintf(f, "%lu ", (u_long) lp->d_drivedata[j]);
    1125     fprintf(f, "\n\n%u partitions:\n", lp->d_npartitions);
    1126     fprintf(f,
    1127             "#        size   offset    fstype   [fsize bsize bps/cpg]\n");
    1128     pp = lp->d_partitions;
    1129     for (i = 0; i < lp->d_npartitions; i++, pp++) {
    1130         if (pp->p_size) {
    1131             fprintf(f, "    %c: %8lu %8lu  ", 'a' + i, (u_long) pp->p_size,
    1132                     (u_long) pp->p_offset);
    1133             if (pp->p_fstype < FSMAXTYPES)
    1134                 fprintf(f, "%8.8s", fstypenames[pp->p_fstype]);
    1135             else
    1136                 fprintf(f, "%8d", pp->p_fstype);
    1137             switch (pp->p_fstype) {
    1138 
    1139             case FS_UNUSED: /* XXX */
    1140                 fprintf(f, "      %5lu %5lu %5.5s ", (u_long) pp->p_fsize,
    1141                         (u_long) (pp->p_fsize * pp->p_frag), "");
    1142                 break;
    1143 
    1144             case FS_BSDFFS:
    1145                 fprintf(f, "      %5lu %5lu %5u ", (u_long) pp->p_fsize,
    1146                         (u_long) (pp->p_fsize * pp->p_frag), pp->p_cpg);
    1147                 break;
    1148 
    1149             case FS_BSDLFS:
    1150                 fprintf(f, "      %5lu %5lu %5d", (u_long) pp->p_fsize,
    1151                         (u_long) (pp->p_fsize * pp->p_frag), pp->p_cpg);
    1152                 break;
    1153 
    1154             default:
    1155                 fprintf(f, "%20.20s", "");
    1156                 break;
    1157             }
    1158             fprintf(f, "\t# (Cyl. %4lu",
    1159                     (u_long) (pp->p_offset / lp->d_secpercyl));
    1160             if (pp->p_offset % lp->d_secpercyl)
    1161                 putc('*', f);
    1162             else
    1163                 putc(' ', f);
    1164             fprintf(f, "- %lu",
    1165                     (u_long) ((pp->p_offset + pp->p_size +
    1166                                  lp->d_secpercyl - 1) / lp->d_secpercyl -
    1167                                 1));
    1168             if (pp->p_size % lp->d_secpercyl)
    1169                 putc('*', f);
    1170             fprintf(f, ")\n");
    1171         }
    1172     }
    1173     fflush(f);
    1174 }
    1175 
    1176 static struct disklabel *get_virgin_disklabel(char *dkname)
    1177 {
    1178     static struct disklabel loclab;
    1179     struct partition *dp;
    1180     char lnamebuf[BBSIZE];
    1181     int f;
    1182     u_int secsize, u;
    1183     off_t mediasize;
    1184 
    1185     (void) snprintf(lnamebuf, BBSIZE, "%s", dkname);
    1186     if ((f = open(lnamebuf, O_RDONLY)) == -1) {
    1187         warn("cannot open %s", lnamebuf);
    1188         return (NULL);
    1189     }
    1190 
    1191     /* New world order */
    1192     if ((ioctl(f, DIOCGMEDIASIZE, &mediasize) != 0)
    1193         || (ioctl(f, DIOCGSECTORSIZE, &secsize) != 0)) {
    1194         close(f);
    1195         return (NULL);
    1196     }
    1197     memset(&loclab, 0, sizeof loclab);
    1198     loclab.d_magic = DISKMAGIC;
    1199     loclab.d_magic2 = DISKMAGIC;
    1200     loclab.d_secsize = secsize;
    1201     loclab.d_secperunit = mediasize / secsize;
    1202 
    1203     /*
    1204      * Nobody in these enligthened days uses the CHS geometry for
    1205      * anything, but nontheless try to get it right.    If we fail
    1206      * to get any good ideas from the device, construct something
    1207      * which is IBM-PC friendly.
    1208      */
    1209     if (ioctl(f, DIOCGFWSECTORS, &u) == 0)
    1210         loclab.d_nsectors = u;
    1211     else
    1212         loclab.d_nsectors = 63;
    1213     if (ioctl(f, DIOCGFWHEADS, &u) == 0)
    1214         loclab.d_ntracks = u;
    1215     else if (loclab.d_secperunit <= 63 * 1 * 1024)
    1216         loclab.d_ntracks = 1;
    1217     else if (loclab.d_secperunit <= 63 * 16 * 1024)
    1218         loclab.d_ntracks = 16;
    1219     else
    1220         loclab.d_ntracks = 255;
    1221     loclab.d_secpercyl = loclab.d_ntracks * loclab.d_nsectors;
    1222     loclab.d_ncylinders = loclab.d_secperunit / loclab.d_secpercyl;
    1223     loclab.d_npartitions = MAXPARTITIONS;
    1224 
    1225     /* Various (unneeded) compat stuff */
    1226     loclab.d_rpm = 3600;
    1227     loclab.d_bbsize = BBSIZE;
    1228     loclab.d_interleave = 1;;
    1229     strncpy(loclab.d_typename, "amnesiac", sizeof(loclab.d_typename));
     1118
     1119        case FS_BSDFFS:
     1120            fprintf(f, "      %5lu %5lu %5u ", (u_long) pp->p_fsize, (u_long) (pp->p_fsize * pp->p_frag), pp->p_cpg);
     1121            break;
     1122
     1123        case FS_BSDLFS:
     1124            fprintf(f, "      %5lu %5lu %5d", (u_long) pp->p_fsize, (u_long) (pp->p_fsize * pp->p_frag), pp->p_cpg);
     1125            break;
     1126
     1127        default:
     1128            fprintf(f, "%20.20s", "");
     1129            break;
     1130        }
     1131        fprintf(f, "\t# (Cyl. %4lu", (u_long) (pp->p_offset / lp->d_secpercyl));
     1132        if (pp->p_offset % lp->d_secpercyl)
     1133            putc('*', f);
     1134        else
     1135            putc(' ', f);
     1136        fprintf(f, "- %lu", (u_long) ((pp->p_offset + pp->p_size + lp->d_secpercyl - 1) / lp->d_secpercyl - 1));
     1137        if (pp->p_size % lp->d_secpercyl)
     1138            putc('*', f);
     1139        fprintf(f, ")\n");
     1140    }
     1141}
     1142fflush(f);
     1143}
     1144
     1145static struct disklabel *get_virgin_disklabel(char *dkname) {
     1146
     1147static struct disklabel loclab;
     1148struct partition *dp;
     1149char *lnamebuf = NULL;
     1150int f;
     1151u_int secsize, u;
     1152off_t mediasize;
     1153
     1154mr_asprintf(lnamebuf, "%s", dkname);
     1155if ((f = open(lnamebuf, O_RDONLY)) == -1) {
     1156    warn("cannot open %s", lnamebuf);
     1157    mr_free(lnamebuf);
     1158    return (NULL);
     1159}
     1160mr_free(lnamebuf);
     1161
     1162/* New world order */
     1163if ((ioctl(f, DIOCGMEDIASIZE, &mediasize) != 0)
     1164    || (ioctl(f, DIOCGSECTORSIZE, &secsize) != 0)) {
     1165    close(f);
     1166    return (NULL);
     1167}
     1168memset(&loclab, 0, sizeof loclab);
     1169loclab.d_magic = DISKMAGIC;
     1170loclab.d_magic2 = DISKMAGIC;
     1171loclab.d_secsize = secsize;
     1172loclab.d_secperunit = mediasize / secsize;
     1173
     1174/*
     1175 * Nobody in these enligthened days uses the CHS geometry for
     1176 * anything, but nontheless try to get it right.    If we fail
     1177 * to get any good ideas from the device, construct something
     1178 * which is IBM-PC friendly.
     1179 */
     1180if (ioctl(f, DIOCGFWSECTORS, &u) == 0)
     1181    loclab.d_nsectors = u;
     1182else
     1183    loclab.d_nsectors = 63;
     1184
     1185if (ioctl(f, DIOCGFWHEADS, &u) == 0)
     1186    loclab.d_ntracks = u;
     1187else if (loclab.d_secperunit <= 63 * 1 * 1024)
     1188    loclab.d_ntracks = 1;
     1189else if (loclab.d_secperunit <= 63 * 16 * 1024)
     1190    loclab.d_ntracks = 16;
     1191else
     1192    loclab.d_ntracks = 255;
     1193loclab.d_secpercyl = loclab.d_ntracks * loclab.d_nsectors;
     1194loclab.d_ncylinders = loclab.d_secperunit / loclab.d_secpercyl;
     1195loclab.d_npartitions = MAXPARTITIONS;
     1196
     1197/* Various (unneeded) compat stuff */
     1198loclab.d_rpm = 3600;
     1199loclab.d_bbsize = BBSIZE;
     1200loclab.d_interleave = 1;;
     1201strncpy(loclab.d_typename, "amnesiac", sizeof(loclab.d_typename));
    12301202
    12311203    dp = &loclab.d_partitions[RAW_PART];
    1232     dp->p_size = loclab.d_secperunit;
    1233     loclab.d_checksum = dkcksum(&loclab);
    1234     close(f);
    1235     return (&loclab);
     1204dp->p_size = loclab.d_secperunit;
     1205loclab.d_checksum = dkcksum(&loclab);
     1206close(f);
     1207return (&loclab);
    12361208}
    12371209
    12381210/* End stolen from /usr/src/sbin/disklabel/disklabel.c. */
    12391211
    1240 char *canonical_name(char *drivename)
    1241 {
    1242     if (drivename) {
    1243         if (strncmp(drivename, "/dev/", 5) == 0) {
    1244             return drivename + 5;
    1245         }
    1246     }
    1247     return drivename;
     1212char *canonical_name(char *drivename) {
     1213
     1214if (drivename) {
     1215    if (strncmp(drivename, "/dev/", 5) == 0) {
     1216        return drivename + 5;
     1217    }
     1218}
     1219return drivename;
    12481220}
    12491221
     
    12551227 * @return The number of errors encountered (0 for success).
    12561228 */
    1257 int label_drive_or_slice(struct mountlist_itself *mountlist,
    1258                          char *drivename, struct disklabel *ret)
    1259 {
    1260     char subdev_str[MAX_STR_LEN];
    1261     char command[MAX_STR_LEN];
    1262     struct disklabel *lp;
    1263     int i, lo = 0;
    1264     int retval = 0;
    1265     char c;
    1266     FILE *ftmp;
    1267 
    1268     lp = get_virgin_disklabel(drivename);
    1269     for (c = 'a'; c <= 'z'; ++c) {
    1270         int idx;
    1271         sprintf(subdev_str, "%s%c", drivename, c);
    1272         if ((idx = find_device_in_mountlist(mountlist, subdev_str)) < 0) {
    1273             lp->d_partitions[c - 'a'].p_size = 0;
    1274             lp->d_partitions[c - 'a'].p_fstype = FS_UNUSED;
    1275         } else {
    1276             lo = c - 'a';
    1277             lp->d_partitions[c - 'a'].p_size = mountlist->el[idx].size * 2;
    1278             lp->d_partitions[c - 'a'].p_fsize = 0;
    1279             lp->d_partitions[c - 'a'].p_frag = 0;
    1280             lp->d_partitions[c - 'a'].p_cpg = 0;
    1281             if (!strcmp(mountlist->el[idx].format, "ufs")
    1282                 || !strcmp(mountlist->el[idx].format, "ffs")
    1283                 || !strcmp(mountlist->el[idx].format, "4.2BSD")) {
    1284                 lp->d_partitions[c - 'a'].p_fstype = FS_BSDFFS;
    1285                 lp->d_partitions[c - 'a'].p_fsize = 2048;
    1286                 lp->d_partitions[c - 'a'].p_frag = 8;
    1287                 lp->d_partitions[c - 'a'].p_cpg = 64;
    1288             } else if (!strcasecmp(mountlist->el[idx].format, "raid")
    1289                          || !strcasecmp(mountlist->el[idx].format, "vinum")) {
    1290                 lp->d_partitions[c - 'a'].p_fstype = FS_VINUM;
    1291             } else if (!strcmp(mountlist->el[idx].format, "swap")) {
    1292                 lp->d_partitions[c - 'a'].p_fstype = FS_SWAP;
    1293             } else
    1294                 lp->d_partitions[c - 'a'].p_fstype = FS_OTHER;
    1295         }
    1296     }
    1297 
    1298     // fix up the offsets
    1299     lp->d_partitions[0].p_offset = 0;
    1300     lp->d_partitions[RAW_PART].p_offset = 0;
    1301     lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
    1302     lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
    1303 
    1304     for (i = 1; i < lp->d_npartitions; ++i) {
    1305         int lastone;
    1306         if ((i == RAW_PART) || (lp->d_partitions[i].p_size == 0))
    1307             continue;
    1308         for (lastone = i - 1; lastone >= 0; lastone--) {
    1309             if ((lp->d_partitions[lastone].p_size)
    1310                 && (lastone != RAW_PART))
    1311                 break;
    1312         }
    1313         lp->d_partitions[i].p_offset =
    1314             lp->d_partitions[lastone].p_offset +
    1315             lp->d_partitions[lastone].p_size;
    1316     }
    1317     if (lp->d_partitions[lo].p_offset + lp->d_partitions[lo].p_size >
    1318         lp->d_secperunit) {
    1319         lp->d_partitions[lo].p_size =
    1320             lp->d_secperunit - lp->d_partitions[lo].p_offset;
    1321     }
    1322 
    1323     ftmp = fopen("/tmp/disklabel", "w");
    1324     display_disklabel(ftmp, lp);
    1325     fclose(ftmp);
    1326     sprintf(command, "disklabel -wr %s auto", canonical_name(drivename));
    1327     retval += run_program_and_log_output(command, TRUE);
    1328     sprintf(command, "disklabel -R %s /tmp/disklabel",
    1329             canonical_name(drivename));
    1330     retval += run_program_and_log_output(command, TRUE);
    1331     if (ret)
    1332         *ret = *lp;
    1333     return retval;
     1229int label_drive_or_slice(struct mountlist_itself *mountlist, char *drivename, struct disklabel *ret) {
     1230
     1231char *subdev_str = NULL;
     1232char *command = NULL;
     1233struct disklabel *lp;
     1234int i, lo = 0;
     1235int retval = 0;
     1236char c;
     1237FILE *ftmp;
     1238
     1239lp = get_virgin_disklabel(drivename);
     1240for (c = 'a'; c <= 'z'; ++c) {
     1241    int idx;
     1242    mr_asprintf(subdev_str, "%s%c", drivename, c);
     1243    if ((idx = find_device_in_mountlist(mountlist, subdev_str)) < 0) {
     1244        lp->d_partitions[c - 'a'].p_size = 0;
     1245        lp->d_partitions[c - 'a'].p_fstype = FS_UNUSED;
     1246    } else {
     1247        lo = c - 'a';
     1248        lp->d_partitions[c - 'a'].p_size = mountlist->el[idx].size * 2;
     1249        lp->d_partitions[c - 'a'].p_fsize = 0;
     1250        lp->d_partitions[c - 'a'].p_frag = 0;
     1251        lp->d_partitions[c - 'a'].p_cpg = 0;
     1252        if (!strcmp(mountlist->el[idx].format, "ufs") || !strcmp(mountlist->el[idx].format, "ffs") || !strcmp(mountlist->el[idx].format, "4.2BSD")) {
     1253            lp->d_partitions[c - 'a'].p_fstype = FS_BSDFFS;
     1254            lp->d_partitions[c - 'a'].p_fsize = 2048;
     1255            lp->d_partitions[c - 'a'].p_frag = 8;
     1256            lp->d_partitions[c - 'a'].p_cpg = 64;
     1257        } else if (!strcasecmp(mountlist->el[idx].format, "raid") || !strcasecmp(mountlist->el[idx].format, "vinum")) {
     1258            lp->d_partitions[c - 'a'].p_fstype = FS_VINUM;
     1259        } else if (!strcmp(mountlist->el[idx].format, "swap")) {
     1260            lp->d_partitions[c - 'a'].p_fstype = FS_SWAP;
     1261        } else
     1262            lp->d_partitions[c - 'a'].p_fstype = FS_OTHER;
     1263    }
     1264    mr_free(subdev_str);
     1265}
     1266
     1267// fix up the offsets
     1268lp->d_partitions[0].p_offset = 0;
     1269lp->d_partitions[RAW_PART].p_offset = 0;
     1270lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
     1271lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
     1272
     1273for (i = 1; i < lp->d_npartitions; ++i) {
     1274    int lastone;
     1275    if ((i == RAW_PART) || (lp->d_partitions[i].p_size == 0))
     1276        continue;
     1277    for (lastone = i - 1; lastone >= 0; lastone--) {
     1278        if ((lp->d_partitions[lastone].p_size) && (lastone != RAW_PART))
     1279            break;
     1280    }
     1281    lp->d_partitions[i].p_offset = lp->d_partitions[lastone].p_offset + lp->d_partitions[lastone].p_size;
     1282}
     1283if (lp->d_partitions[lo].p_offset + lp->d_partitions[lo].p_size > lp->d_secperunit) {
     1284    lp->d_partitions[lo].p_size = lp->d_secperunit - lp->d_partitions[lo].p_offset;
     1285}
     1286
     1287ftmp = fopen("/tmp/disklabel", "w");
     1288display_disklabel(ftmp, lp);
     1289fclose(ftmp);
     1290mr_asprintf(command, "disklabel -wr %s auto", canonical_name(drivename));
     1291retval += run_program_and_log_output(command, TRUE);
     1292mr_free(command);
     1293
     1294mr_asprintf(command, "disklabel -R %s /tmp/disklabel", canonical_name(drivename));
     1295retval += run_program_and_log_output(command, TRUE);
     1296mr_free(command);
     1297
     1298if (ret)
     1299    *ret = *lp;
     1300return retval;
    13341301}
    13351302#endif
     
    13421309 * @return 0 for success, nonzero for failure.
    13431310 */
    1344 int partition_drive(struct mountlist_itself *mountlist, char *drivename)
    1345 {
    1346     /** int *************************************************************/
    1347     int current_devno;
    1348     int previous_devno = 0;
    1349     int lino;
    1350     int retval = 0;
    1351     int i;
    1352     FILE *pout_to_fdisk = NULL;
     1311int partition_drive(struct mountlist_itself *mountlist, char *drivename) {
     1312
     1313/** int *************************************************************/
     1314int current_devno;
     1315int previous_devno = 0;
     1316int lino;
     1317int retval = 0;
     1318int i;
     1319FILE *pout_to_fdisk = NULL;
    13531320
    13541321#ifdef __FreeBSD__
    1355     bool fbsd_part = FALSE;
    1356     char subdev_str[MAX_STR_LEN];
    1357 #endif
    1358 
    1359     /** long long *******************************************************/
    1360     long long partsize;
    1361 
    1362     /** buffers *********************************************************/
    1363     char *device_str;
    1364     char *format;
    1365     char *tmp;
    1366     char *tmp1 = NULL;
    1367 
    1368     /** end *************************************************************/
    1369 
    1370     assert(mountlist != NULL);
    1371     assert_string_is_neither_NULL_nor_zerolength(drivename);
    1372 
    1373     malloc_string(device_str);
    1374     malloc_string(format);
    1375     malloc_string(tmp);
    1376 
    1377     sprintf(tmp, "Partitioning drive %s", drivename);
    1378     log_it(tmp);
     1322bool fbsd_part = FALSE;
     1323char *subdev_str = NULL;
     1324#endif
     1325
     1326/** long long *******************************************************/
     1327long long partsize;
     1328
     1329/** buffers *********************************************************/
     1330char *device_str;
     1331char *format = NULL;
     1332char *tmp = NULL;
     1333char *tmp1 = NULL;
     1334
     1335/** end *************************************************************/
     1336
     1337assert(mountlist != NULL);
     1338assert_string_is_neither_NULL_nor_zerolength(drivename);
     1339
     1340
     1341log_it("Partitioning drive %s", drivename);
    13791342
    13801343#if __FreeBSD__
     
    13821345    pout_to_fdisk = NULL;
    13831346#else
    1384     make_hole_for_file(FDISK_LOG);
    1385     sprintf(tmp, "parted2fdisk %s >> %s 2>> %s", drivename, FDISK_LOG, FDISK_LOG);
    1386     pout_to_fdisk = popen(tmp, "w");
    1387     if (!pout_to_fdisk) {
    1388         log_to_screen("Cannot call parted2fdisk to configure %s", drivename);
    1389         paranoid_free(device_str);
    1390         paranoid_free(format);
    1391         paranoid_free(tmp);
    1392         return (1);
    1393     }
    1394 #endif
    1395     for (current_devno = 1; current_devno < 99; current_devno++) {
    1396         build_partition_name(device_str, drivename, current_devno);
    1397         lino = find_device_in_mountlist(mountlist, device_str);
    1398 
    1399         if (lino < 0) {
    1400             // device not found in mountlist
     1347make_hole_for_file(FDISK_LOG);
     1348mr_asprintf(tmp, "parted2fdisk %s >> %s 2>> %s", drivename, FDISK_LOG, FDISK_LOG);
     1349pout_to_fdisk = popen(tmp, "w");
     1350if (!pout_to_fdisk) {
     1351    log_to_screen("Cannot call parted2fdisk to configure %s", drivename);
     1352    mr_free(tmp);
     1353    return (1);
     1354}
     1355mr_free(tmp);
     1356#endif
     1357
     1358malloc_string(device_str);
     1359
     1360for (current_devno = 1; current_devno < 99; current_devno++) {
     1361    build_partition_name(device_str, drivename, current_devno);
     1362    lino = find_device_in_mountlist(mountlist, device_str);
     1363
     1364    if (lino < 0) {
     1365        // device not found in mountlist
    14011366#if __FreeBSD__
    14021367            // If this is the first partition (just as a sentinel value),
     
    14071372                // try DangerouslyDedicated mode
    14081373                for (c = 'a'; c <= 'z'; c++) {
    1409                     sprintf(subdev_str, "%s%c", drivename, c);
    1410                     if (find_device_in_mountlist(mountlist, subdev_str) >
    1411                         0) {
     1374                    mr_asprintf(subdev_str, "%s%c", drivename, c);
     1375                    if (find_device_in_mountlist(mountlist, subdev_str) > 0) {
    14121376                        fbsd_part = TRUE;
    14131377                    }
     1378                    mr_free(subdev_str);
    14141379                }
    14151380                if (fbsd_part) {
     
    14251390                    }
    14261391                    paranoid_free(device_str);
    1427                     paranoid_free(format);
    1428                     paranoid_free(tmp);
    14291392                    return r;
    14301393                }
    14311394            }
    14321395            for (c = 'a'; c <= 'z'; c++) {
    1433                 sprintf(subdev_str, "%s%c", device_str, c);
     1396                mr_assprintf(subdev_str, "%s%c", device_str, c);
    14341397                if (find_device_in_mountlist(mountlist, subdev_str) > 0) {
    14351398                    fbsd_part = TRUE;
    14361399                }
     1400                mr_free(subdev_str);
    14371401            }
    14381402            // Now we check the subpartitions of the current partition.
     
    14401404                int i, line;
    14411405
    1442                 strcpy(format, "ufs");
     1406                mr_asprintf(format, "ufs");
    14431407                partsize = 0;
    14441408                for (i = 'a'; i < 'z'; ++i) {
    1445                     sprintf(subdev_str, "%s%c", device_str, i);
     1409                    mr_asprintf(subdev_str, "%s%c", device_str, i);
    14461410                    line = find_device_in_mountlist(mountlist, subdev_str);
     1411                    mr_free(subdev_str);
     1412
    14471413                    if (line > 0) {
    14481414                        // We found one! Add its size to the total size.
     
    14561422            continue;
    14571423#endif
    1458         }
    1459 
    1460         /* OK, we've found partition /dev/hdxN in mountlist; let's prep it */
    1461         /* For FreeBSD, that is     /dev/adXsY */
    1462 
    1463         log_it("Found partition %s in mountlist", device_str);
    1464         if (!previous_devno) {
    1465 
    1466             log_it("Wiping %s's partition table", drivename);
     1424    }
     1425
     1426    /* OK, we've found partition /dev/hdxN in mountlist; let's prep it */
     1427    /* For FreeBSD, that is     /dev/adXsY */
     1428
     1429    log_it("Found partition %s in mountlist", device_str);
     1430    if (!previous_devno) {
     1431
     1432        log_it("Wiping %s's partition table", drivename);
    14671433#if __FreeBSD__
    14681434            // FreeBSD doesn't let you write to blk devices in <512byte chunks.
    1469 //          sprintf(tmp, "dd if=/dev/zero of=%s count=1 bs=512", drivename);
    1470 //          if (run_program_and_log_output(tmp, TRUE)) {
    14711435            file = open(drivename, O_WRONLY);
    14721436            if (file != -1) {
    1473                 sprintf(tmp,
    1474                         "Warning - unable to open %s for wiping it's partition table",
    1475                         drivename);
    1476                 log_to_screen(tmp);
     1437                log_to_screnn("Warning - unable to open %s for wiping it's partition table", drivename);
    14771438            }
    14781439
    14791440            for (i = 0; i < 512; i++) {
    14801441                if (!write(file, "\0", 1)) {
    1481                     sprintf(tmp, "Warning - unable to write to %s",
    1482                             drivename);
    1483                     log_to_screen(tmp);
     1442                    log_to_screen("Warning - unable to write to %s", drivename);
    14841443                }
    14851444            }
     
    14911450                fflush(pout_to_fdisk);
    14921451            }
    1493 //          sprintf(tmp, "dd if=/dev/zero of=%s count=1 bs=512", drivename);
    1494 //          run_program_and_log_output(tmp, 1);
    1495 #endif
    1496             if (current_devno > 1) {
    1497                 previous_devno =
    1498                     make_dummy_partitions(pout_to_fdisk, drivename,
    1499                                             current_devno);
    1500             }
    1501         }
     1452#endif
     1453        if (current_devno > 1) {
     1454            previous_devno = make_dummy_partitions(pout_to_fdisk, drivename, current_devno);
     1455        }
     1456    }
    15021457#ifdef __FreeBSD__
    1503         if (!fbsd_part) {
    1504 #endif
    1505 
    1506             strcpy(format, mountlist->el[lino].format);
    1507             partsize = mountlist->el[lino].size;
     1458    if (!fbsd_part) {
     1459        mr_free(format);
     1460#endif
     1461
     1462        mr_asprintf(format, "%s", mountlist->el[lino].format);
     1463        partsize = mountlist->el[lino].size;
    15081464
    15091465#ifdef __FreeBSD__
    1510         }
     1466    }
    15111467#endif
    15121468
    15131469#ifndef __IA64__
    1514         if (current_devno == 5 && previous_devno == 4) {
    1515             log_to_screen
    1516                 ("You must leave at least one partition spare as the Extended partition.");
    1517             paranoid_free(device_str);
    1518             paranoid_free(format);
    1519             paranoid_free(tmp);
    1520             return (1);
    1521         }
    1522 #endif
    1523 
    1524         retval +=
    1525             partition_device(pout_to_fdisk, drivename, current_devno,
    1526                              previous_devno, format, partsize);
     1470    if (current_devno == 5 && previous_devno == 4) {
     1471        log_to_screen("You must leave at least one partition spare as the Extended partition.");
     1472        paranoid_free(device_str);
     1473        mr_free(format);
     1474        return (1);
     1475    }
     1476#endif
     1477
     1478    retval += partition_device(pout_to_fdisk, drivename, current_devno, previous_devno, format, partsize);
     1479    mr_free(format);
    15271480
    15281481#ifdef __FreeBSD__
    1529         if ((current_devno <= 4) && fbsd_part) {
    1530             sprintf(tmp, "disklabel -B %s", basename(device_str));
    1531             retval += label_drive_or_slice(mountlist, device_str, 0);
    1532             if (system(tmp)) {
    1533                 log_to_screen
    1534                     ("Warning! Unable to make the slice bootable.");
    1535             }
    1536         }
    1537 #endif
    1538 
    1539         previous_devno = current_devno;
    1540     }
    1541 
    1542     if (pout_to_fdisk) {
    1543         // close fdisk
    1544         fput_string_one_char_at_a_time(pout_to_fdisk, "p\n");
    1545         fput_string_one_char_at_a_time(pout_to_fdisk, "w\n");
    1546         paranoid_pclose(pout_to_fdisk);
    1547         paranoid_system("sync");
    1548         log_msg(0,"------------------- fdisk.log looks like this ------------------");
    1549         sprintf(tmp, "cat %s >> %s", FDISK_LOG, MONDO_LOGFILE);
    1550         paranoid_system(tmp);
    1551         // mark relevant partition as bootable
    1552         mr_asprintf(tmp1,"make-me-bootable /tmp/mountlist.txt %s",drivename);
    1553         call_program_and_get_last_line_of_output(tmp1);
    1554         mr_free(tmp1);
    1555         log_msg(0,"------------------- end of fdisk.log...       ------------------");
    1556         paranoid_system("sync");
    1557         sprintf(tmp, "tail -n6 %s | grep -F \"16: \"", FDISK_LOG);
    1558         if (!run_program_and_log_output(tmp, 5)) {
    1559             g_partition_table_locked_up++;
    1560         }
    1561         sprintf(tmp, "partprobe %s", drivename);
    1562         if (!run_program_and_log_output(tmp, 5)) {
    1563             g_partition_table_locked_up--;
    1564         }
    1565         if (g_partition_table_locked_up > 0) {
    1566             log_to_screen
    1567                 ("A flaw in the Linux kernel has locked the partition table. Even calling partprobe did not suceed :-(");
    1568         }
    1569     }
    1570     paranoid_free(device_str);
    1571     paranoid_free(format);
    1572     paranoid_free(tmp);
    1573     return (retval);
     1482    if ((current_devno <= 4) && fbsd_part) {
     1483        mr_asprintf(tmp, "disklabel -B %s", basename(device_str));
     1484        retval += label_drive_or_slice(mountlist, device_str, 0);
     1485        if (system(tmp)) {
     1486            log_to_screen("Warning! Unable to make the slice bootable.");
     1487        }
     1488        mr_free(tmp);
     1489    }
     1490#endif
     1491
     1492    previous_devno = current_devno;
     1493}
     1494
     1495if (pout_to_fdisk) {
     1496    // close fdisk
     1497    fput_string_one_char_at_a_time(pout_to_fdisk, "p\n");
     1498    fput_string_one_char_at_a_time(pout_to_fdisk, "w\n");
     1499    paranoid_pclose(pout_to_fdisk);
     1500    paranoid_system("sync");
     1501    log_msg(0,"------------------- fdisk.log looks like this ------------------");
     1502    mr_asprintf(tmp, "cat %s >> %s", FDISK_LOG, MONDO_LOGFILE);
     1503    paranoid_system(tmp);
     1504    mr_free(tmp);
     1505
     1506    // mark relevant partition as bootable
     1507    mr_asprintf(tmp1,"make-me-bootable /tmp/mountlist.txt %s",drivename);
     1508    call_program_and_get_last_line_of_output(tmp1);
     1509    mr_free(tmp1);
     1510
     1511    log_msg(0,"------------------- end of fdisk.log...       ------------------");
     1512    paranoid_system("sync");
     1513    mr_asprintf(tmp, "tail -n6 %s | grep -F \"16: \"", FDISK_LOG);
     1514    if (!run_program_and_log_output(tmp, 5)) {
     1515        g_partition_table_locked_up++;
     1516    }
     1517    mr_free(tmp);
     1518
     1519    mr_asprintf(tmp, "partprobe %s", drivename);
     1520    if (!run_program_and_log_output(tmp, 5)) {
     1521        g_partition_table_locked_up--;
     1522    }
     1523    mr_free(tmp);
     1524
     1525    if (g_partition_table_locked_up > 0) {
     1526        log_to_screen("A flaw in the Linux kernel has locked the partition table. Even calling partprobe did not suceed :-(");
     1527    }
     1528}
     1529paranoid_free(device_str);
     1530return (retval);
    15741531}
    15751532
     
    15831540 * @return 0 for success, nonzero for failure.
    15841541 */
    1585 int partition_device(FILE * pout_to_fdisk, const char *drive, int partno,
    1586                      int prev_partno, const char *format,
    1587                      long long partsize)
    1588 {
    1589     /** int **************************************************************/
    1590     int retval = 0;
    1591     int res = 0;
    1592 
    1593     /** buffers **********************************************************/
    1594     char *program;
    1595     char *partition_name;
    1596     char *tmp;
    1597     char *logfile;
    1598     char *output = NULL;
    1599 
    1600     /** pointers **********************************************************/
    1601     char *p;
    1602     char *part_table_fmt = NULL;
    1603     FILE *fout;
    1604 
    1605     /** end ***************************************************************/
    1606 
    1607     malloc_string(program);
    1608     malloc_string(partition_name);
    1609     malloc_string(tmp);
    1610     malloc_string(logfile);
    1611 
    1612     assert_string_is_neither_NULL_nor_zerolength(drive);
    1613     assert(format != NULL);
    1614 
    1615     log_it("partition_device('%s', %d, %d, '%s', %lld) --- starting",
    1616              drive, partno, prev_partno, format, partsize);
    1617 
    1618     if (!strncmp(drive, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) {
    1619         sprintf(tmp, "Not partitioning %s - it is a virtual drive", drive);
    1620         log_it(tmp);
    1621         paranoid_free(program);
    1622         paranoid_free(partition_name);
    1623         paranoid_free(tmp);
    1624         paranoid_free(logfile);
    1625         return (0);
    1626     }
    1627     build_partition_name(partition_name, drive, partno);
    1628     if (partsize <= 0) {
    1629         sprintf(tmp, "Partitioning device %s (max size)", partition_name);
     1542int partition_device(FILE * pout_to_fdisk, const char *drive, int partno, int prev_partno, const char *format, long long partsize) {
     1543
     1544/** int **************************************************************/
     1545int retval = 0;
     1546int res = 0;
     1547
     1548/** buffers **********************************************************/
     1549char *program = NULL;
     1550char *partition_name;
     1551char *tmp = NULL;
     1552char *output = NULL;
     1553
     1554/** pointers **********************************************************/
     1555char *part_table_fmt = NULL;
     1556FILE *fout;
     1557
     1558/** end ***************************************************************/
     1559
     1560assert_string_is_neither_NULL_nor_zerolength(drive);
     1561assert(format != NULL);
     1562
     1563log_it("partition_device('%s', %d, %d, '%s', %lld) --- starting", drive, partno, prev_partno, format, partsize);
     1564
     1565if (!strncmp(drive, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) {
     1566    log_it("Not partitioning %s - it is a virtual drive", drive);
     1567    return (0);
     1568}
     1569
     1570malloc_string(partition_name);
     1571build_partition_name(partition_name, drive, partno);
     1572if (partsize <= 0) {
     1573    mr_asprintf(tmp, "Partitioning device %s (max size)", partition_name);
     1574} else {
     1575    mr_asprintf(tmp, "Partitioning device %s (%lld MB)", partition_name, (long long) partsize / 1024);
     1576}
     1577update_progress_form(tmp);
     1578log_it(tmp);
     1579mr_free(tmp);
     1580
     1581if (is_this_device_mounted(partition_name)) {
     1582    log_to_screen("%s is mounted, and should not be partitioned", partition_name);
     1583    paranoid_free(partition_name);
     1584    return (1);
     1585}
     1586
     1587
     1588mr_asprintf(program, "parted2fdisk %s >> %s 2>> %s", drive, MONDO_LOGFILE, MONDO_LOGFILE);
     1589
     1590/* BERLIOS: should not be called each time */
     1591part_table_fmt = which_partition_format(drive);
     1592mr_asprintf(output, "");
     1593
     1594/* make it a primary/extended/logical */
     1595if (partno <= 4) {
     1596    mr_strcat(output, "n\np\n%d\n", partno);
     1597} else {
     1598    /* MBR needs an extended partition if more than 4 partitions */
     1599    if (strcmp(part_table_fmt, "MBR") == 0) {
     1600        if (partno == 5) {
     1601            if (prev_partno >= 4) {
     1602                log_to_screen("You need to leave at least one partition free, for 'extended/logical'");
     1603                paranoid_free(partition_name);
     1604                paranoid_free(output);
     1605                return (1);
     1606            } else {
     1607                mr_strcat(output, "n\ne\n%d\n\n\n", prev_partno + 1);
     1608            }
     1609        }
     1610        mr_strcat(output, "n\nl\n");
    16301611    } else {
    1631         sprintf(tmp, "Partitioning device %s (%lld MB)", partition_name,
    1632                 (long long) partsize / 1024);
    1633     }
    1634     update_progress_form(tmp);
    1635     log_it(tmp);
    1636 
    1637     if (is_this_device_mounted(partition_name)) {
    1638         sprintf(tmp, "%s is mounted, and should not be partitioned",
    1639                 partition_name);
    1640         log_to_screen(tmp);
    1641         paranoid_free(program);
    1642         paranoid_free(partition_name);
    1643         paranoid_free(tmp);
    1644         paranoid_free(logfile);
    1645         return (1);
    1646 /*
    1647     } else if (does_partition_exist(drive, partno)) {
    1648         sprintf(tmp, "%s already has a partition", partition_name);
    1649         log_to_screen(tmp);
    1650         return (1);
    1651 */
    1652     }
    1653 
    1654 
    1655     /*  sprintf(tmp,"Partitioning %s  ",partition_name); */
    1656     /*  mvaddstr_and_log_it(g_currentY+1,30,tmp); */
    1657     p = (char *) strrchr(partition_name, '/');
    1658     sprintf(logfile, "/tmp/fdisk.log.%s", ++p);
    1659     sprintf(program, "parted2fdisk %s >> %s 2>> %s", drive, MONDO_LOGFILE,
    1660             MONDO_LOGFILE);
    1661 
    1662     /* BERLIOS: should not be called each time */
    1663     part_table_fmt = which_partition_format(drive);
    1664     mr_asprintf(output, "");
    1665     /* make it a primary/extended/logical */
    1666     if (partno <= 4) {
     1612        /* GPT allows more than 4 primary partitions */
    16671613        mr_strcat(output, "n\np\n%d\n", partno);
    1668     } else {
    1669         /* MBR needs an extended partition if more than 4 partitions */
    1670         if (strcmp(part_table_fmt, "MBR") == 0) {
    1671             if (partno == 5) {
    1672                 if (prev_partno >= 4) {
    1673                     log_to_screen
    1674                         ("You need to leave at least one partition free, for 'extended/logical'");
    1675                     paranoid_free(program);
    1676                     paranoid_free(partition_name);
    1677                     paranoid_free(tmp);
    1678                     paranoid_free(logfile);
    1679                     paranoid_free(output);
    1680                     return (1);
    1681                 } else {
    1682                     mr_strcat(output, "n\ne\n%d\n\n\n", prev_partno + 1);
    1683                 }
    1684             }
    1685             mr_strcat(output, "n\nl\n");
    1686         } else {
    1687             /* GPT allows more than 4 primary partitions */
    1688             mr_strcat(output, "n\np\n%d\n", partno);
    1689         }
    1690     }
    1691     mr_free(part_table_fmt);
    1692 
    1693     mr_strcat(output, "\n");    /*start block (ENTER for next free blk */
    1694     if (partsize > 0) {
    1695         if (!strcmp(format, "7")) {
    1696             log_msg(1, "Adding 512K, just in case");
    1697             partsize += 512;
    1698         }
    1699         mr_strcat(output, "+%lldK", (long long) (partsize));
    1700     }
    1701     mr_strcat(output, "\n");
     1614    }
     1615}
     1616mr_free(part_table_fmt);
     1617
     1618mr_strcat(output, "\n");    /*start block (ENTER for next free blk */
     1619if (partsize > 0) {
     1620    if (!strcmp(format, "7")) {
     1621        log_msg(1, "Adding 512K, just in case");
     1622        partsize += 512;
     1623    }
     1624    mr_strcat(output, "+%lldK", (long long) (partsize));
     1625}
     1626mr_strcat(output, "\n");
    17021627#if 0
    17031628/*
    17041629#endif
    1705     sprintf(tmp,"PARTSIZE = +%ld",(long)partsize);
    1706     log_it(tmp);
    1707     log_it("---fdisk command---");
    1708     log_it(output);
    1709     log_it("---end of fdisk---");
     1630log_it("PARTSIZE = +%ld",(long)partsize);
     1631log_it("---fdisk command---");
     1632log_it(output);
     1633log_it("---end of fdisk---");
    17101634#if 0
    17111635*/
     
    17131637
    17141638
    1715     if (pout_to_fdisk) {
    1716         log_msg(1, "Doing the new all-in-one fdisk thing");
    1717         log_msg(1, "output = '%s'", output);
    1718         fput_string_one_char_at_a_time(pout_to_fdisk, output);
    1719         fput_string_one_char_at_a_time(pout_to_fdisk, "\n\np\n");
    1720         strcpy(tmp, last_line_of_file(FDISK_LOG));
    1721         if (strstr(tmp, " (m ")) {
    1722             log_msg(1, "Successfully created partition %d on %s", partno, drive);
     1639if (pout_to_fdisk) {
     1640    log_msg(1, "Doing the new all-in-one fdisk thing");
     1641    log_msg(1, "output = '%s'", output);
     1642    fput_string_one_char_at_a_time(pout_to_fdisk, output);
     1643    fput_string_one_char_at_a_time(pout_to_fdisk, "\n\np\n");
     1644    mr_asprintf(tmp, "%s", last_line_of_file(FDISK_LOG));
     1645    if (strstr(tmp, " (m ")) {
     1646        log_msg(1, "Successfully created partition %d on %s", partno, drive);
     1647    } else {
     1648        log_msg(1, "last line = %s", tmp);
     1649        log_msg(1, "Failed to create partition %d on %s; sending 'Enter'...", partno, drive);
     1650    }
     1651    mr_free(tmp);
     1652
     1653    if (!retval) {
     1654        log_msg(1, "Trying to set partition %d type now on %s", partno, drive);
     1655        retval = set_partition_type(pout_to_fdisk, drive, partno, format, partsize);
     1656        if (retval) {
     1657            log_msg(1, "Failed. Trying again...");
     1658            retval = set_partition_type(pout_to_fdisk, drive, partno, format, partsize);
     1659        }
     1660    }
     1661    if (retval) {
     1662        log_msg(1, "...but failed to set type");
     1663    }
     1664} else {
     1665    mr_strcat(output, "w\n\n");
     1666    if (g_fprep) {
     1667        fprintf(g_fprep, "echo \"%s\" | %s\n", output, program);
     1668    }
     1669    /* write to disk; close fdisk's stream */
     1670    if (!(fout = popen(program, "w"))) {
     1671        log_OS_error("can't popen-out to program");
     1672    } else {
     1673        fputs(output, fout);
     1674        paranoid_pclose(fout);
     1675    }
     1676
     1677    if (!does_partition_exist(drive, partno) && partsize > 0) {
     1678        log_it("Vaccum-packing");
     1679        g_current_progress--;
     1680        res = partition_device(pout_to_fdisk, drive, partno, prev_partno, format, -1);
     1681        if (res) {
     1682            log_it("Failed to vacuum-pack %s", partition_name);
     1683            retval++;
    17231684        } else {
    1724             log_msg(1, "last line = %s", tmp);
    1725             log_msg(1, "Failed to create partition %d on %s; sending 'Enter'...", partno, drive);
    1726         }
    1727         if (!retval) {
    1728             log_msg(1, "Trying to set partition %d type now on %s", partno, drive);
    1729             retval =
    1730                 set_partition_type(pout_to_fdisk, drive, partno, format,
    1731                                      partsize);
    1732             if (retval) {
    1733                 log_msg(1, "Failed. Trying again...");
    1734                 retval =
    1735                     set_partition_type(pout_to_fdisk, drive, partno,
    1736                                          format, partsize);
     1685            retval = 0;
     1686        }
     1687    }
     1688    if (does_partition_exist(drive, partno)) {
     1689        retval = set_partition_type(pout_to_fdisk, drive, partno, format, partsize);
     1690        if (retval) {
     1691            log_it("Partitioned %s but failed to set its type", partition_name);
     1692        } else {
     1693            if (partsize > 0) {
     1694                log_to_screen("Partition %s created+configured OK", partition_name);
     1695            } else {
     1696                log_it("Returning from a successful vacuum-pack");
    17371697            }
    17381698        }
    1739         if (retval) {
    1740             log_msg(1, "...but failed to set type");
    1741         }
    17421699    } else {
    1743         mr_strcat(output, "w\n\n");
    1744         if (g_fprep) {
    1745             fprintf(g_fprep, "echo \"%s\" | %s\n", output, program);
    1746         }
    1747         /* write to disk; close fdisk's stream */
    1748         if (!(fout = popen(program, "w"))) {
    1749             log_OS_error("can't popen-out to program");
     1700        mr_asprintf(tmp, "Failed to partition %s", partition_name);
     1701        if (partsize > 0) {
     1702            log_to_screen(tmp);
    17501703        } else {
    1751             fputs(output, fout);
    1752             paranoid_pclose(fout);
    1753         }
    1754         if (!does_partition_exist(drive, partno) && partsize > 0) {
    1755             log_it("Vaccum-packing");
    1756             g_current_progress--;
    1757             res =
    1758                 partition_device(pout_to_fdisk, drive, partno, prev_partno,
    1759                                  format, -1);
    1760             if (res) {
    1761                 sprintf(tmp, "Failed to vacuum-pack %s", partition_name);
    1762                 log_it(tmp);
    1763                 retval++;
    1764             } else {
    1765                 retval = 0;
    1766             }
    1767         }
    1768         if (does_partition_exist(drive, partno)) {
    1769             retval =
    1770                 set_partition_type(pout_to_fdisk, drive, partno, format,
    1771                                      partsize);
    1772             if (retval) {
    1773                 sprintf(tmp, "Partitioned %s but failed to set its type",
    1774                         partition_name);
    1775                 log_it(tmp);
    1776             } else {
    1777                 if (partsize > 0) {
    1778                     sprintf(tmp, "Partition %s created+configured OK",
    1779                             partition_name);
    1780                     log_to_screen(tmp);
    1781                 } else {
    1782                     log_it("Returning from a successful vacuum-pack");
    1783                 }
    1784             }
    1785         } else {
    1786             sprintf(tmp, "Failed to partition %s", partition_name);
    1787             if (partsize > 0) {
    1788                 log_to_screen(tmp);
    1789             } else {
    1790                 log_it(tmp);
    1791             }
    1792             retval++;
    1793         }
    1794     }
    1795     paranoid_free(output);
    1796 
    1797     g_current_progress++;
    1798     log_it("partition_device() --- leaving");
    1799     paranoid_free(program);
    1800     paranoid_free(partition_name);
    1801     paranoid_free(tmp);
    1802     paranoid_free(logfile);
    1803     return (retval);
     1704            log_it(tmp);
     1705        }
     1706        mr_free(tmp);
     1707        retval++;
     1708    }
     1709}
     1710mr_free(program);
     1711paranoid_free(output);
     1712
     1713g_current_progress++;
     1714log_it("partition_device() --- leaving");
     1715paranoid_free(partition_name);
     1716return (retval);
    18041717}
    18051718
     
    18131726 * Use format_everything() for that.
    18141727 */
    1815 int partition_everything(struct mountlist_itself *mountlist)
    1816 {
    1817     /** int ************************************************************/
    1818     int lino;
    1819     int retval = 0;
    1820     int i;
    1821     int res;
    1822 
    1823     /** buffer *********************************************************/
    1824     struct list_of_disks *drivelist;
    1825     /*  struct mountlist_itself new_mtlist, *mountlist; */
    1826 
    1827     /** end ************************************************************/
    1828 
    1829     drivelist = malloc(sizeof(struct list_of_disks));
    1830     assert(mountlist != NULL);
    1831 
    1832     log_it("partition_everything() --- starting");
    1833     mvaddstr_and_log_it(g_currentY, 0, "Partitioning hard drives        ");
    1834     /*  mountlist=orig_mtlist; */
    1835     if (mountlist_contains_raid_devices(mountlist)) {
    1836         /*      mountlist=&new_mtlist; */
    1837         /*      extrapolate_mountlist_to_include_raid_partitions(mountlist,orig_mtlist); */
    1838         log_msg(0,
    1839                 "Mountlist, including the partitions incorporated in RAID devices:-");
    1840         for (i = 0; i < mountlist->entries; i++) {
    1841             log_it(mountlist->el[i].device);
    1842         }
    1843         log_msg(0, "End of mountlist.");
    1844     }
    1845     log_msg(0, "Stopping all LVMs, just in case");
    1846     if (!g_text_mode) {
    1847         newtSuspend();
    1848     }
    1849     do_my_funky_lvm_stuff(TRUE, FALSE); // just remove old partitions
    1850     if (!g_text_mode) {
    1851         newtResume();
    1852     }
    1853     log_msg(0, "Stopping all software RAID devices, just in case");
    1854     stop_all_raid_devices(mountlist);
    1855     log_msg(0, "Done.");
    1856 
    1857 /* 
    1858     if (does_file_exist("/tmp/i-want-my-lvm"))
    1859         {
    1860           wipe_MBRs_and_reboot_if_necessary(mountlist); // i.e. if it wasn't done recently
    1861         }
    1862 */
    1863 
    1864     open_progress_form("Partitioning devices",
    1865                          "I am now going to partition all your drives.",
    1866                          "This should not take more than five minutes.", "",
    1867                          mountlist->entries);
    1868 
    1869     make_list_of_drives_in_mountlist(mountlist, drivelist);
    1870 
    1871     /* partition each drive */
    1872     for (lino = 0; lino < drivelist->entries; lino++) {
    1873         res = partition_drive(mountlist, drivelist->el[lino].device);
    1874         retval += res;
    1875     }
    1876     close_progress_form();
    1877     if (retval) {
    1878         mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
    1879         log_to_screen
    1880             ("Errors occurred during the partitioning of your hard drives.");
    1881     } else {
    1882         mvaddstr_and_log_it(g_currentY++, 74, "Done.");
    1883         paranoid_system("rm -f /tmp/fdisk*.log 2> /dev/null");
    1884     }
     1728int partition_everything(struct mountlist_itself *mountlist) {
     1729
     1730/** int ************************************************************/
     1731int lino;
     1732int retval = 0;
     1733int i;
     1734int res;
     1735
     1736/** buffer *********************************************************/
     1737struct list_of_disks *drivelist;
     1738
     1739/** end ************************************************************/
     1740
     1741drivelist = malloc(sizeof(struct list_of_disks));
     1742assert(mountlist != NULL);
     1743
     1744log_it("partition_everything() --- starting");
     1745mvaddstr_and_log_it(g_currentY, 0, "Partitioning hard drives        ");
     1746
     1747if (mountlist_contains_raid_devices(mountlist)) {
     1748    log_msg(0, "Mountlist, including the partitions incorporated in RAID devices:-");
     1749    for (i = 0; i < mountlist->entries; i++) {
     1750        log_it(mountlist->el[i].device);
     1751    }
     1752    log_msg(0, "End of mountlist.");
     1753}
     1754log_msg(0, "Stopping all LVMs, just in case");
     1755if (!g_text_mode) {
    18851756    newtSuspend();
    1886     paranoid_system("clear");
     1757}
     1758do_my_funky_lvm_stuff(TRUE, FALSE); // just remove old partitions
     1759if (!g_text_mode) {
    18871760    newtResume();
    1888     paranoid_free(drivelist);
    1889     return (retval);
    1890 }
    1891 
    1892 
    1893 
     1761}
     1762log_msg(0, "Stopping all software RAID devices, just in case");
     1763stop_all_raid_devices(mountlist);
     1764log_msg(0, "Done.");
     1765
     1766open_progress_form("Partitioning devices", "I am now going to partition all your drives.", "This should not take more than five minutes.", "", mountlist->entries);
     1767
     1768make_list_of_drives_in_mountlist(mountlist, drivelist);
     1769
     1770/* partition each drive */
     1771for (lino = 0; lino < drivelist->entries; lino++) {
     1772    res = partition_drive(mountlist, drivelist->el[lino].device);
     1773    retval += res;
     1774}
     1775close_progress_form();
     1776if (retval) {
     1777    mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
     1778    log_to_screen("Errors occurred during the partitioning of your hard drives.");
     1779} else {
     1780    mvaddstr_and_log_it(g_currentY++, 74, "Done.");
     1781    paranoid_system("rm -f /tmp/fdisk*.log 2> /dev/null");
     1782}
     1783newtSuspend();
     1784paranoid_system("clear");
     1785newtResume();
     1786paranoid_free(drivelist);
     1787return (retval);
     1788}
    18941789
    18951790
     
    19041799 * @return 0 for success, nonzero for failure.
    19051800 */
    1906 int set_partition_type(FILE * pout_to_fdisk, const char *drive, int partno,
    1907                          const char *format, long long partsize)
    1908 {
    1909     /** buffers *********************************************************/
    1910     char *partition;
    1911     char *command;
    1912     char *output = NULL;
    1913     char *tmp;
    1914     char *partcode;
    1915     char *logfile;
    1916 
    1917     /** pointers *********************************************************/
    1918     char *p;
    1919     FILE *fout;
    1920 
    1921     /** int **************************************************************/
    1922     int res = 0;
    1923 
    1924     /** end **************************************************************/
    1925 
    1926     assert_string_is_neither_NULL_nor_zerolength(drive);
    1927     assert(format != NULL);
    1928 
    1929     malloc_string(partition);
    1930     malloc_string(command);
    1931     malloc_string(tmp);
    1932     malloc_string(partcode);
    1933     malloc_string(logfile);
    1934 
    1935     build_partition_name(partition, drive, partno);
    1936     p = (char *) strrchr(partition, '/');
    1937     sprintf(logfile, "/tmp/fdisk-set-type.%s.log", ++p);
    1938     if (strcmp(format, "swap") == 0) {
    1939         strcpy(partcode, "82");
    1940     } else if (strcmp(format, "vfat") == 0) {
    1941         if (partsize / 1024 > 8192) {
    1942             strcpy(partcode, "c");
     1801int set_partition_type(FILE * pout_to_fdisk, const char *drive, int partno, const char *format, long long partsize) {
     1802
     1803/** buffers *********************************************************/
     1804char *partition;
     1805char *command = NULL;
     1806char *output = NULL;
     1807char *tmp = NULL;
     1808char *partcode = NULL;
     1809
     1810/** pointers *********************************************************/
     1811FILE *fout;
     1812
     1813/** int **************************************************************/
     1814int res = 0;
     1815
     1816/** end **************************************************************/
     1817
     1818assert_string_is_neither_NULL_nor_zerolength(drive);
     1819assert(format != NULL);
     1820
     1821malloc_string(partition);
     1822
     1823build_partition_name(partition, drive, partno);
     1824if (strcmp(format, "swap") == 0) {
     1825    mr_asprintf(partcode, "82");
     1826} else if (strcmp(format, "vfat") == 0) {
     1827    if (partsize / 1024 > 8192) {
     1828        mr_asprintf(partcode, "c");
     1829    } else {
     1830        mr_asprintf(partcode, "b");
     1831    }
     1832} else if (strcmp(format, "ext2") == 0
     1833             || strcmp(format, "reiserfs") == 0
     1834             || strcmp(format, "ext3") == 0
     1835             || strcmp(format, "ext4") == 0
     1836             || strcmp(format, "xfs") == 0
     1837             || strcmp(format, "jfs") == 0
     1838                 || strcmp(format, "btrfs") == 0) {
     1839    mr_asprintf(partcode, "83");
     1840} else if (strcmp(format, "minix") == 0) {
     1841    mr_asprintf(partcode, "81");
     1842} else if (strcmp(format, "vmfs3") == 0) {
     1843    mr_asprintf(partcode, "fb");
     1844} else if (strcmp(format, "vmkcore") == 0) {
     1845    mr_asprintf(partcode, "fc");
     1846} else if (strcmp(format, "raid") == 0) {
     1847    mr_asprintf(partcode, "fd");
     1848} else if (strcmp(format, "ntfs") == 0) {
     1849    mr_asprintf(partcode, "7");
     1850} else if ((strcmp(format, "ufs") == 0)
     1851             || (strcmp(format, "ffs") == 0)) { /* raid autodetect */
     1852    mr_asprintf(partcode, "a5");
     1853} else if (strcmp(format, "lvm") == 0) {
     1854    mr_asprintf(partcode, "8e");
     1855} else if (format[0] == '\0') { /* LVM physical partition */
     1856    mr_asprintf(partcode, "");
     1857} else if (strlen(format) >= 1 && strlen(format) <= 2) {
     1858    mr_asprintf(partcode, format);
     1859} else {
     1860    /* probably an image */
     1861    mr_asprintf(tmp, "Unknown format ('%s') - using supplied string anyway", format);
     1862    mvaddstr_and_log_it(g_currentY++, 0, tmp);
     1863    mr_free(tmp);
     1864
     1865#ifdef __FreeBSD__
     1866    mr_asprintf(partcode, format);  // was a5
     1867#else
     1868    mr_asprintf(partcode, format);  // was 83
     1869#endif
     1870}
     1871log_msg(1, "Setting %s's type to %s (%s)", partition, format, partcode);
     1872if ((strcmp(partcode,"") != 0) && strcmp(partcode, "83")) { /* no need to set type if 83: 83 is default */
     1873
     1874    if (pout_to_fdisk) {
     1875        res = 0;
     1876        fput_string_one_char_at_a_time(pout_to_fdisk, "t\n");
     1877        if (partno > 1
     1878            || strstr(last_line_of_file(FDISK_LOG), " (1-4)")) {
     1879            log_msg(5, "Specifying partno (%d) - yay", partno);
     1880            mr_asprintf(tmp, "%d\n", partno);
     1881            fput_string_one_char_at_a_time(pout_to_fdisk, tmp);
     1882            log_msg(5, "A - last line = '%s'", last_line_of_file(FDISK_LOG));
     1883            mr_free(tmp);
     1884        }
     1885
     1886        mr_asprintf(tmp, "%s\n", partcode);
     1887        fput_string_one_char_at_a_time(pout_to_fdisk, tmp);
     1888        mr_free(tmp);
     1889
     1890        log_msg(5, "B - last line = '%s'",
     1891                last_line_of_file(FDISK_LOG));
     1892        fput_string_one_char_at_a_time(pout_to_fdisk, "\n");
     1893        log_msg(5, "C - last line = '%s'",
     1894                last_line_of_file(FDISK_LOG));
     1895
     1896        mr_asprintf(tmp, "%s", last_line_of_file(FDISK_LOG));
     1897        if (!strstr(tmp, " (m ")) {
     1898            log_msg(1, "last line = '%s'; part type set failed", tmp);
     1899            res++;
     1900            fput_string_one_char_at_a_time(pout_to_fdisk, "\n");
     1901        }
     1902        mr_free(tmp);
     1903
     1904        fput_string_one_char_at_a_time(pout_to_fdisk, "p\n");
     1905    } else {
     1906        mr_asprintf(output, "t\n%d\n%s\nw\n", partno, partcode);
     1907        mr_asprintf(command, "parted2fdisk %s >> %s 2>> %s", drive, MONDO_LOGFILE, MONDO_LOGFILE);
     1908        log_msg(5, "output = '%s'", output);
     1909        log_msg(5, "partno=%d; partcode=%s", partno, partcode);
     1910        log_msg(5, "command = '%s'", command);
     1911        fout = popen(command, "w");
     1912        if (!fout) {
     1913            log_OS_error(command);
     1914            res = 1;
    19431915        } else {
    1944             strcpy(partcode, "b");
    1945         }
    1946     } else if (strcmp(format, "ext2") == 0
    1947                  || strcmp(format, "reiserfs") == 0
    1948                  || strcmp(format, "ext3") == 0
    1949                  || strcmp(format, "ext4") == 0
    1950                  || strcmp(format, "xfs") == 0
    1951                  || strcmp(format, "jfs") == 0
    1952                      || strcmp(format, "btrfs") == 0) {
    1953         strcpy(partcode, "83");
    1954     } else if (strcmp(format, "minix") == 0) {
    1955         strcpy(partcode, "81");
    1956     } else if (strcmp(format, "vmfs3") == 0) {
    1957         strcpy(partcode, "fb");
    1958     } else if (strcmp(format, "vmkcore") == 0) {
    1959         strcpy(partcode, "fc");
    1960     } else if (strcmp(format, "raid") == 0) {
    1961         strcpy(partcode, "fd");
    1962     } else if (strcmp(format, "ntfs") == 0) {
    1963         strcpy(partcode, "7");
    1964     } else if ((strcmp(format, "ufs") == 0)
    1965                  || (strcmp(format, "ffs") == 0)) { /* raid autodetect */
    1966         strcpy(partcode, "a5");
    1967     } else if (strcmp(format, "lvm") == 0) {
    1968         strcpy(partcode, "8e");
    1969     } else if (format[0] == '\0') { /* LVM physical partition */
    1970         partcode[0] = '\0';
    1971     } else if (strlen(format) >= 1 && strlen(format) <= 2) {
    1972         strcpy(partcode, format);
    1973     } else {
    1974         /* probably an image */
    1975         sprintf(tmp,
    1976                 "Unknown format ('%s') - using supplied string anyway",
    1977                 format);
    1978         mvaddstr_and_log_it(g_currentY++, 0, tmp);
     1916            res = 0;
     1917            fprintf(fout, "%s", output);
     1918            paranoid_pclose(fout);
     1919        }
     1920        mr_free(command);
     1921        paranoid_free(output);
     1922    }
     1923}
     1924mr_free(partcode);
     1925
     1926paranoid_free(partition);
     1927
     1928return (res);
     1929}
     1930
     1931
     1932int start_raid_device(char *raid_device) {
     1933
     1934/** int *************************************************************/
     1935int res;
     1936int retval = 0;
     1937
     1938/** buffers *********************************************************/
     1939char *program = NULL;
     1940
     1941/** end *************************************************************/
     1942
     1943assert_string_is_neither_NULL_nor_zerolength(raid_device);
     1944
    19791945#ifdef __FreeBSD__
    1980         strcpy(partcode, format);   // was a5
     1946if (is_this_device_mounted(raid_device)) {
     1947    log_it("Can't start %s when it's mounted!", raid_device);
     1948    return 1;
     1949}
     1950mr_asprintf(program, "vinum start -f %s", raid_device);
    19811951#else
    1982         strcpy(partcode, format);   // was 83
    1983 #endif
    1984     }
    1985     sprintf(tmp, "Setting %s's type to %s (%s)", partition, format,
    1986             partcode);
    1987     log_msg(1, tmp);
    1988     if (partcode[0] != '\0' && strcmp(partcode, "83")) {    /* no need to set type if 83: 83 is default */
    1989 
    1990         if (pout_to_fdisk) {
    1991             res = 0;
    1992             fput_string_one_char_at_a_time(pout_to_fdisk, "t\n");
    1993             if (partno > 1
    1994                 || strstr(last_line_of_file(FDISK_LOG), " (1-4)")) {
    1995                 log_msg(5, "Specifying partno (%d) - yay", partno);
    1996                 sprintf(tmp, "%d\n", partno);
    1997                 fput_string_one_char_at_a_time(pout_to_fdisk, tmp);
    1998                 log_msg(5, "A - last line = '%s'",
    1999                         last_line_of_file(FDISK_LOG));
    2000             }
    2001 
    2002             sprintf(tmp, "%s\n", partcode);
    2003             fput_string_one_char_at_a_time(pout_to_fdisk, tmp);
    2004             log_msg(5, "B - last line = '%s'",
    2005                     last_line_of_file(FDISK_LOG));
    2006             fput_string_one_char_at_a_time(pout_to_fdisk, "\n");
    2007             log_msg(5, "C - last line = '%s'",
    2008                     last_line_of_file(FDISK_LOG));
    2009 
    2010             strcpy(tmp, last_line_of_file(FDISK_LOG));
    2011             if (!strstr(tmp, " (m ")) {
    2012                 log_msg(1, "last line = '%s'; part type set failed", tmp);
    2013                 res++;
    2014                 fput_string_one_char_at_a_time(pout_to_fdisk, "\n");
    2015             }
    2016             fput_string_one_char_at_a_time(pout_to_fdisk, "p\n");
    2017         } else {
    2018             mr_asprintf(output, "t\n%d\n%s\nw\n", partno, partcode);
    2019             sprintf(command, "parted2fdisk %s >> %s 2>> %s", drive,
    2020                     MONDO_LOGFILE, MONDO_LOGFILE);
    2021             log_msg(5, "output = '%s'", output);
    2022             log_msg(5, "partno=%d; partcode=%s", partno, partcode);
    2023             log_msg(5, "command = '%s'", command);
    2024             fout = popen(command, "w");
    2025             if (!fout) {
    2026                 log_OS_error(command);
    2027                 res = 1;
    2028             } else {
    2029                 res = 0;
    2030                 fprintf(fout, "%s", output);
    2031                 paranoid_pclose(fout);
    2032             }
    2033             paranoid_free(output);
    2034         }
    2035         if (res) {
    2036             log_OS_error(command);
    2037         }
    2038     }
    2039 
    2040     paranoid_free(partition);
    2041     paranoid_free(command);
    2042     paranoid_free(tmp);
    2043     paranoid_free(partcode);
    2044     paranoid_free(logfile);
    2045 
    2046     return (res);
    2047 }
    2048 
    2049 
    2050 int start_raid_device(char *raid_device)
    2051 {
    2052     /** int *************************************************************/
    2053     int res;
    2054     int retval = 0;
    2055 
    2056     /** buffers *********************************************************/
    2057     char *program;
    2058 
    2059     /** end *************************************************************/
    2060 
    2061     assert_string_is_neither_NULL_nor_zerolength(raid_device);
    2062     malloc_string(program);
    2063 
    2064 #ifdef __FreeBSD__
    2065     if (is_this_device_mounted(raid_device)) {
    2066         log_it("Can't start %s when it's mounted!", raid_device);
    2067         return 1;
    2068     }
    2069     sprintf(program, "vinum start -f %s", raid_device);
    2070 #else
    2071     sprintf(program, "raidstart %s", raid_device);
    2072 #endif
    2073     log_msg(1, "program = %s", program);
    2074     res = run_program_and_log_output(program, 1);
    2075     if (g_fprep) {
    2076         fprintf(g_fprep, "%s\n", program);
    2077     }
    2078     if (res) {
    2079         log_msg(1, "Warning - failed to start RAID device %s",
    2080                 raid_device);
    2081     }
    2082     retval += res;
    2083     sleep(1);
    2084     return (retval);
     1952mr_asprintf(program, "raidstart %s", raid_device);
     1953#endif
     1954log_msg(1, "program = %s", program);
     1955res = run_program_and_log_output(program, 1);
     1956if (g_fprep) {
     1957    fprintf(g_fprep, "%s\n", program);
     1958}
     1959mr_free(program);
     1960
     1961if (res) {
     1962    log_msg(1, "Warning - failed to start RAID device %s", raid_device);
     1963}
     1964retval += res;
     1965sleep(1);
     1966return (retval);
    20851967}
    20861968
     
    20921974 * @return 0 for success, nonzero for failure.
    20931975 */
    2094 int stop_raid_device(char *raid_device)
    2095 {
    2096     /** int *************************************************************/
    2097     int res;
    2098     int retval = 0;
    2099 
    2100     /** buffers *********************************************************/
    2101     char *program;
    2102 
    2103     /** end *************************************************************/
    2104 
    2105     assert_string_is_neither_NULL_nor_zerolength(raid_device);
    2106     malloc_string(program);
     1976int stop_raid_device(char *raid_device) {
     1977
     1978/** int *************************************************************/
     1979int res;
     1980int retval = 0;
     1981
     1982/** buffers *********************************************************/
     1983char *program = NULL;
     1984
     1985/** end *************************************************************/
     1986
     1987assert_string_is_neither_NULL_nor_zerolength(raid_device);
    21071988
    21081989#ifdef __FreeBSD__
    2109     if (is_this_device_mounted(raid_device)) {
    2110         log_it("Can't stop %s when it's mounted!", raid_device);
    2111         return 1;
    2112     }
    2113     sprintf(program, "vinum stop -f %s", raid_device);
     1990if (is_this_device_mounted(raid_device)) {
     1991    log_it("Can't stop %s when it's mounted!", raid_device);
     1992    return 1;
     1993}
     1994mr_asprintf(program, "vinum stop -f %s", raid_device);
    21141995#else
    2115         // use raidstop if it exists, otherwise use mdadm
    2116         if (run_program_and_log_output("which raidstop", FALSE)) {
    2117         sprintf(program, "mdadm -S %s", raid_device);
    2118     } else {
    2119         sprintf(program, "raidstop %s", raid_device);
    2120     }
    2121 #endif
    2122     log_msg(1, "program = %s", program);
    2123     res = run_program_and_log_output(program, 1);
    2124     if (g_fprep) {
    2125         fprintf(g_fprep, "%s\n", program);
    2126     }
    2127     if (res) {
    2128         log_msg(1, "Warning - failed to stop RAID device %s", raid_device);
    2129     }
    2130     retval += res;
    2131     return (retval);
    2132 }
    2133 
    2134 
    2135 int start_all_raid_devices(struct mountlist_itself *mountlist)
    2136 {
    2137     int i;
    2138     int retval = 0;
    2139     int res;
    2140 
    2141     for (i = 0; i < mountlist->entries; i++) {
    2142         if (!strncmp
    2143             (mountlist->el[i].device, RAID_DEVICE_STUB,
    2144             strlen(RAID_DEVICE_STUB))) {
    2145             log_msg(1, "Starting %s", mountlist->el[i].device);
    2146             res = start_raid_device(mountlist->el[i].device);
    2147             retval += res;
    2148         }
    2149     }
    2150     if (retval) {
    2151         log_msg(1, "Started all s/w raid devices OK");
    2152     } else {
    2153         log_msg(1, "Failed to start some/all s/w raid devices");
    2154     }
    2155     return (retval);
     1996// use raidstop if it exists, otherwise use mdadm
     1997if (run_program_and_log_output("which raidstop", FALSE)) {
     1998    mr_asprintf(program, "mdadm -S %s", raid_device);
     1999} else {
     2000    mr_asprintf(program, "raidstop %s", raid_device);
     2001}
     2002#endif
     2003log_msg(1, "program = %s", program);
     2004res = run_program_and_log_output(program, 1);
     2005if (g_fprep) {
     2006    fprintf(g_fprep, "%s\n", program);
     2007}
     2008mr_free(program);
     2009
     2010if (res) {
     2011    log_msg(1, "Warning - failed to stop RAID device %s", raid_device);
     2012}
     2013retval += res;
     2014return (retval);
     2015}
     2016
     2017
     2018int start_all_raid_devices(struct mountlist_itself *mountlist) {
     2019
     2020int i;
     2021int retval = 0;
     2022int res;
     2023
     2024for (i = 0; i < mountlist->entries; i++) {
     2025    if (!strncmp(mountlist->el[i].device, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) {
     2026        log_msg(1, "Starting %s", mountlist->el[i].device);
     2027        res = start_raid_device(mountlist->el[i].device);
     2028        retval += res;
     2029    }
     2030}
     2031if (retval) {
     2032    log_msg(1, "Started all s/w raid devices OK");
     2033} else {
     2034    log_msg(1, "Failed to start some/all s/w raid devices");
     2035}
     2036return (retval);
    21562037}
    21572038
     
    21622043 * @bug @p mountlist is not used.
    21632044 */
    2164 int stop_all_raid_devices(struct mountlist_itself *mountlist)
    2165 {
    2166     /** int *************************************************************/
    2167     int retval = 0;
    2168 
    2169     /** char ************************************************************/
    2170     char *incoming;
     2045int stop_all_raid_devices(struct mountlist_itself *mountlist) {
     2046
     2047/** int *************************************************************/
     2048int retval = 0;
     2049
     2050/** char ************************************************************/
     2051char *incoming;
    21712052#ifndef __FreeBSD__
    2172     char *dev;
    2173 #endif
    2174     /** pointers ********************************************************/
     2053char *dev;
     2054#endif
     2055/** pointers ********************************************************/
    21752056#ifndef __FreeBSD__
    2176     char *p;
    2177 #endif
    2178     FILE *fin;
    2179     char *q;
    2180     int i;
    2181 
    2182     /** end ****************************************************************/
    2183 
    2184     malloc_string(dev);
    2185     malloc_string(incoming);
    2186     assert(mountlist != NULL);
    2187 
    2188     for (i = 0; i < 3; i++) {
     2057char *p;
     2058#endif
     2059FILE *fin;
     2060char *q;
     2061int i;
     2062
     2063/** end ****************************************************************/
     2064
     2065malloc_string(incoming);
     2066assert(mountlist != NULL);
     2067
     2068for (i = 0; i < 3; i++) {
    21892069#ifdef __FreeBSD__
    2190         fin =
    2191             popen
    2192             ("vinum list | grep '^[PVS]' | sed 's/S/1/;s/P/2/;s/V/3/' | sort | cut -d' ' -f2",
    2193              "r");
    2194         if (!fin) {
     2070    fin = popen("vinum list | grep '^[PVS]' | sed 's/S/1/;s/P/2/;s/V/3/' | sort | cut -d' ' -f2", "r");
     2071    if (!fin) {
     2072        paranoid_free(incoming);
     2073        return (1);
     2074    }
     2075    for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL); q = fgets(incoming, MAX_STR_LEN - 1, fin)) {
     2076        retval += stop_raid_device(incoming);
     2077    }
     2078#else
     2079    fin = fopen("/proc/mdstat", "r");
     2080    if (!fin) {
     2081        log_OS_error("/proc/mdstat");
     2082        paranoid_free(incoming);
     2083        return (1);
     2084    }
     2085    for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL); q = fgets(incoming, MAX_STR_LEN - 1, fin)) {
     2086        for (p = incoming; *p != '\0' && (*p != 'm' || *(p + 1) != 'd' || !isdigit(*(p + 2))); p++);
     2087        if (*p != '\0') {
     2088            malloc_string(dev);
     2089            sprintf(dev, "/dev/%s", p);
     2090            for (p = dev; *p > 32; p++);
     2091            *p = '\0';
     2092            retval += stop_raid_device(dev);
    21952093            paranoid_free(dev);
    2196             paranoid_free(incoming);
    2197             return (1);
    2198         }
    2199         for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL);
    2200              q = fgets(incoming, MAX_STR_LEN - 1, fin)) {
    2201             retval += stop_raid_device(incoming);
    2202         }
    2203 #else
    2204         fin = fopen("/proc/mdstat", "r");
    2205         if (!fin) {
    2206             log_OS_error("/proc/mdstat");
    2207             paranoid_free(dev);
    2208             paranoid_free(incoming);
    2209             return (1);
    2210         }
    2211         for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL);
    2212              q = fgets(incoming, MAX_STR_LEN - 1, fin)) {
    2213             for (p = incoming;
    2214                  *p != '\0' && (*p != 'm' || *(p + 1) != 'd'
    2215                                 || !isdigit(*(p + 2))); p++);
    2216             if (*p != '\0') {
    2217                 sprintf(dev, "/dev/%s", p);
    2218                 for (p = dev; *p > 32; p++);
    2219                 *p = '\0';
    2220                 retval += stop_raid_device(dev);
    2221             }
    2222         }
    2223 #endif
    2224     }
    2225     paranoid_fclose(fin);
    2226     if (retval) {
    2227         log_msg(1, "Warning - unable to stop some RAID devices");
    2228     }
    2229     paranoid_free(dev);
    2230     paranoid_free(incoming);
    2231     paranoid_system("sync");
    2232     paranoid_system("sync");
    2233     paranoid_system("sync");
    2234     sleep(1);
    2235     return (retval);
     2094        }
     2095    }
     2096#endif
     2097}
     2098paranoid_fclose(fin);
     2099if (retval) {
     2100    log_msg(1, "Warning - unable to stop some RAID devices");
     2101}
     2102paranoid_free(incoming);
     2103paranoid_system("sync");
     2104paranoid_system("sync");
     2105paranoid_system("sync");
     2106sleep(1);
     2107return (retval);
    22362108}
    22372109
     
    22442116 * @return 0 for success, nonzero for failure.
    22452117 */
    2246 int which_format_command_do_i_need(char *format, char *program)
    2247 {
    2248     /** int *************************************************************/
    2249     int res = 0;
    2250 
    2251     /** buffers *********************************************************/
    2252     char *tmp;
    2253 
    2254     /** end ***************************************************************/
    2255 
    2256     malloc_string(tmp);
    2257     assert_string_is_neither_NULL_nor_zerolength(format);
    2258     assert(program != NULL);
    2259 
    2260     if (strcmp(format, "swap") == 0) {
     2118int which_format_command_do_i_need(char *format, char *program) {
     2119
     2120/** int *************************************************************/
     2121int res = 0;
     2122
     2123/** buffers *********************************************************/
     2124
     2125/** end ***************************************************************/
     2126
     2127assert_string_is_neither_NULL_nor_zerolength(format);
     2128assert(program != NULL);
     2129
     2130if (strcmp(format, "swap") == 0) {
    22612131#ifdef __FreeBSD__
    2262         strcpy(program, "true");
     2132    strcpy(program, "true");
    22632133#else
    2264         strcpy(program, "mkswap");
    2265 #endif
    2266     } else if (strcmp(format, "vfat") == 0) {
    2267         strcpy(program, "format-and-kludge-vfat");
     2134    strcpy(program, "mkswap");
     2135#endif
     2136} else if (strcmp(format, "vfat") == 0) {
     2137    strcpy(program, "format-and-kludge-vfat");
    22682138#ifndef __FreeBSD__
    2269     } else if (strcmp(format, "reiserfs") == 0) {
    2270         strcpy(program, "mkreiserfs -ff");
    2271     } else if (strcmp(format, "xfs") == 0) {
    2272         strcpy(program, "mkfs.xfs -f -q");
    2273     } else if (strcmp(format, "jfs") == 0) {
    2274         strcpy(program, "mkfs.jfs");
    2275     } else if (strcmp(format, "ext3") == 0) {
    2276         strcpy(program, "mkfs -t ext3 -F -q");
    2277     } else if (strcmp(format, "ext4") == 0) {
    2278         strcpy(program, "mkfs -t ext4 -F -q");
    2279     } else if (strcmp(format, "btrfs") == 0) {
    2280               strcpy(program, "mkfs.btrfs");
    2281     } else if (strcmp(format, "minix") == 0) {
    2282         strcpy(program, "mkfs.minix");
    2283     } else if (strcmp(format, "vmfs") == 0) {
    2284         strcpy(program, "mkfs -t vmfs");
    2285     } else if (strcmp(format, "ntfs") == 0) {
    2286         /*
    2287         * mkfs.ntfs treats the '-c' switch as 'specify cluster size'
    2288         * so the default "mkfs -t %s -c" command structure fails
    2289         */
    2290         strcpy(program, "mkfs -t ntfs");
    2291     } else if (strcmp(format, "ocfs2") == 0) {
    2292         /*
    2293         * For existing OCFS2 volumes, mkfs.ocfs2 ensures the volume is not mounted on any node in the cluster before formatting. For that to work, mkfs.ocfs2 expects the O2CB cluster service to be running. Specify this option to disable this check.
    2294         *
    2295         */
    2296         strcpy(program, "mkfs -t ocfs2 -F");
    2297 #endif
    2298     } else if (strcmp(format, "ext2") == 0) {
    2299         strcpy(program, "mke2fs -F -q");
    2300     } else {
     2139} else if (strcmp(format, "reiserfs") == 0) {
     2140    strcpy(program, "mkreiserfs -ff");
     2141} else if (strcmp(format, "xfs") == 0) {
     2142    strcpy(program, "mkfs.xfs -f -q");
     2143} else if (strcmp(format, "jfs") == 0) {
     2144    strcpy(program, "mkfs.jfs");
     2145} else if (strcmp(format, "ext3") == 0) {
     2146    strcpy(program, "mkfs -t ext3 -F -q");
     2147} else if (strcmp(format, "ext4") == 0) {
     2148    strcpy(program, "mkfs -t ext4 -F -q");
     2149} else if (strcmp(format, "btrfs") == 0) {
     2150    strcpy(program, "mkfs.btrfs");
     2151} else if (strcmp(format, "minix") == 0) {
     2152    strcpy(program, "mkfs.minix");
     2153} else if (strcmp(format, "vmfs") == 0) {
     2154    strcpy(program, "mkfs -t vmfs");
     2155} else if (strcmp(format, "ntfs") == 0) {
     2156    /*
     2157    * mkfs.ntfs treats the '-c' switch as 'specify cluster size'
     2158    * so the default "mkfs -t %s -c" command structure fails
     2159    */
     2160    strcpy(program, "mkfs -t ntfs");
     2161} else if (strcmp(format, "ocfs2") == 0) {
     2162    /*
     2163    * For existing OCFS2 volumes, mkfs.ocfs2 ensures the volume is not mounted on any node in the cluster before formatting. For that to work, mkfs.ocfs2 expects the O2CB cluster service to be running. Specify this option to disable this check.
     2164    *
     2165    */
     2166    strcpy(program, "mkfs -t ocfs2 -F");
     2167#endif
     2168} else if (strcmp(format, "ext2") == 0) {
     2169    strcpy(program, "mke2fs -F -q");
     2170} else {
    23012171#ifdef __FreeBSD__
    2302         sprintf(program, "newfs_%s", format);
     2172    sprintf(program, "newfs_%s", format);
    23032173#else
    2304         sprintf(program, "mkfs -t %s -c", format);  // -c checks for bad blocks
    2305 #endif
    2306         sprintf(tmp, "Unknown format (%s) - assuming '%s' will do", format,
    2307                 program);
    2308         log_it(tmp);
    2309         res = 0;
    2310     }
    2311     paranoid_free(tmp);
    2312     return (res);
     2174    sprintf(program, "mkfs -t %s -c", format);  // -c checks for bad blocks
     2175#endif
     2176    log_it("Unknown format (%s) - assuming '%s' will do", format, program);
     2177    res = 0;
     2178}
     2179return (res);
    23132180}
    23142181
     
    23252192 * @param drive_name The drive to resize.
    23262193 */
    2327 void resize_drive_proportionately_to_suit_new_drives(struct mountlist_itself
    2328                                                      *mountlist,
    2329                                                      char *drive_name)
    2330 {
    2331     /**buffers **********************************************************/
    2332     char *tmp;
    2333 
    2334     /** int *************************************************************/
    2335     int partno, lastpart;
    2336 
    2337     /** float ***********************************************************/
    2338     float factor;
    2339     long long new_size;
    2340 
    2341     /** long *************************************************************/
    2342     long long newsizL = 0LL;
    2343     long long totalsizL = 0LL;
    2344     long long current_size_of_drive = 0LL;  /* use KB interally for precision */
    2345     long long original_size_of_drive = 0LL; /* use KB interally for precision */
    2346     struct mountlist_reference *drivemntlist;
    2347 
    2348     /** structures *******************************************************/
    2349 
    2350     /** end **************************************************************/
    2351 
    2352     assert(mountlist != NULL);
    2353     assert_string_is_neither_NULL_nor_zerolength(drive_name);
    2354 
    2355     if (strlen(drive_name) >= strlen(RAID_DEVICE_STUB)) {
    2356         if (strncmp(drive_name, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))
    2357             == 0) {
    2358             return;
    2359         }
    2360     }
    2361 
    2362     current_size_of_drive = (long long) get_phys_size_of_drive(drive_name) * 1024LL;
    2363 
    2364     if (current_size_of_drive <= 0LL) {
    2365         log_it("Not resizing to match %s - can't find drive", drive_name);
     2194void resize_drive_proportionately_to_suit_new_drives(struct mountlist_itself *mountlist, char *drive_name) {
     2195
     2196/**buffers **********************************************************/
     2197char *tmp = NULL;
     2198
     2199/** int *************************************************************/
     2200int partno, lastpart;
     2201
     2202/** float ***********************************************************/
     2203float factor;
     2204long long new_size;
     2205
     2206/** long *************************************************************/
     2207long long newsizL = 0LL;
     2208long long totalsizL = 0LL;
     2209long long current_size_of_drive = 0LL;  /* use KB interally for precision */
     2210long long original_size_of_drive = 0LL; /* use KB interally for precision */
     2211struct mountlist_reference *drivemntlist;
     2212
     2213/** structures *******************************************************/
     2214
     2215/** end **************************************************************/
     2216
     2217assert(mountlist != NULL);
     2218assert_string_is_neither_NULL_nor_zerolength(drive_name);
     2219
     2220if (strlen(drive_name) >= strlen(RAID_DEVICE_STUB)) {
     2221    if (strncmp(drive_name, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))
     2222        == 0) {
    23662223        return;
    23672224    }
    2368     mr_asprintf(tmp, "Expanding entries to suit drive %s (%lld MB)", drive_name, current_size_of_drive / 1024);
    2369     log_to_screen(tmp);
    2370     mr_free(tmp);
    2371 
    2372     drivemntlist = malloc(sizeof(struct mountlist_reference));
    2373     drivemntlist->el = malloc(sizeof(struct mountlist_line *) * MAX_MOUNTLIST_ENTRIES);
    2374 
    2375     if (!drivemntlist) {
    2376         fatal_error("Cannot malloc temporary mountlist\n");
    2377     }
    2378     create_mountlist_for_drive(mountlist, drive_name, drivemntlist);
    2379 
    2380     for (partno = 0; partno < drivemntlist->entries; partno++) {
    2381         if (drivemntlist->el[partno]->size > 0LL) {
    2382             /* Keep KB here */
    2383             original_size_of_drive += drivemntlist->el[partno]->size;
    2384         }
    2385     }
    2386 
    2387     if (original_size_of_drive <= 0LL) {
    2388         mr_asprintf(tmp, "Cannot resize %s's entries. Drive not found.", drive_name);
    2389         log_to_screen(tmp);
    2390         mr_free(tmp);
    2391         return;
    2392     }
    2393     factor = ((float)current_size_of_drive/(float)original_size_of_drive);
    2394     mr_asprintf(tmp, "Disk %s was %lld MB; is now %lld MB; Proportionally resizing partitions (factor ~= %.5f)",
    2395             drive_name, original_size_of_drive/1024, current_size_of_drive/1024, factor);
    2396     log_to_screen(tmp);
    2397     mr_free(tmp);
    2398 
    2399     lastpart = drivemntlist->entries - 1;
    2400     for (partno = 0; partno < drivemntlist->entries; partno++) {
    2401         /* the 'atoi' thing is to make sure we don't try to resize _images_, whose formats will be numeric */
    2402         if (!atoi(drivemntlist->el[partno]->format)) {
    2403             new_size = (long long)((drivemntlist->el[partno]->size) * factor);
    2404         } else {
    2405             new_size = drivemntlist->el[partno]->size;
    2406         }
    2407 
    2408         if (!strcmp(drivemntlist->el[partno]->mountpoint, "image")) {
    2409             log_msg(1, "Skipping %s (%s) because it's an image",
    2410                     drivemntlist->el[partno]->device,
    2411                     drivemntlist->el[partno]->mountpoint);
    2412         }
    2413         newsizL = new_size;
    2414 
    2415         /* Do not apply the factor if partition was of negative size */
    2416         if (newsizL < 0LL) {
    2417             newsizL = drivemntlist->el[partno]->size;
    2418         }
    2419         totalsizL += newsizL;
    2420 
    2421         mr_asprintf(tmp, "Changing %s from %lld KB to %lld KB", drivemntlist->el[partno]->device, drivemntlist->el[partno]->size, newsizL);
    2422         log_to_screen(tmp);
    2423         mr_free(tmp);
    2424         drivemntlist->el[partno]->size = newsizL;
    2425     }
    2426     // Ensures over-allocation alert and prompt for interactive mode does not happen
    2427     if (totalsizL > current_size_of_drive) {
    2428         mr_asprintf(tmp, "Last partition size calculated would be over-allocated, reducing %s from %lld KB to %lld KB.", drivemntlist->el[lastpart]->device, drivemntlist->el[lastpart]->size, drivemntlist->el[lastpart]->size - (totalsizL - current_size_of_drive));
    2429         drivemntlist->el[drivemntlist->entries-1]->size -= (totalsizL - current_size_of_drive);
    2430     } else if (totalsizL < current_size_of_drive) {
    2431         mr_asprintf(tmp, "Last partition size calculated would be under-allocated, increasing %s from %lld KB to %lld KB.",drivemntlist->el[lastpart]->device, drivemntlist->el[lastpart]->size, drivemntlist->el[lastpart]->size + (current_size_of_drive - totalsizL));
    2432         drivemntlist->el[drivemntlist->entries-1]->size += (current_size_of_drive - totalsizL);
    2433     }
    2434     log_to_screen(tmp);
    2435     mr_free(tmp);
    2436     mr_asprintf(tmp, "final_size = %lld MB", current_size_of_drive / 1024);
    2437     log_to_screen(tmp);
    2438     mr_free(tmp);
     2225}
     2226
     2227current_size_of_drive = (long long) get_phys_size_of_drive(drive_name) * 1024LL;
     2228
     2229if (current_size_of_drive <= 0LL) {
     2230    log_it("Not resizing to match %s - can't find drive", drive_name);
     2231    return;
     2232}
     2233log_to_screen("Expanding entries to suit drive %s (%lld MB)", drive_name, current_size_of_drive / 1024);
     2234
     2235drivemntlist = malloc(sizeof(struct mountlist_reference));
     2236drivemntlist->el = malloc(sizeof(struct mountlist_line *) * MAX_MOUNTLIST_ENTRIES);
     2237
     2238if (!drivemntlist) {
     2239    fatal_error("Cannot malloc temporary mountlist\n");
     2240}
     2241create_mountlist_for_drive(mountlist, drive_name, drivemntlist);
     2242
     2243for (partno = 0; partno < drivemntlist->entries; partno++) {
     2244    if (drivemntlist->el[partno]->size > 0LL) {
     2245        /* Keep KB here */
     2246        original_size_of_drive += drivemntlist->el[partno]->size;
     2247    }
     2248}
     2249
     2250if (original_size_of_drive <= 0LL) {
     2251    log_to_screen("Cannot resize %s's entries. Drive not found.", drive_name);
     2252    return;
     2253}
     2254factor = ((float)current_size_of_drive/(float)original_size_of_drive);
     2255log_to_screen("Disk %s was %lld MB; is now %lld MB; Proportionally resizing partitions (factor ~= %.5f)", drive_name, original_size_of_drive/1024, current_size_of_drive/1024, factor);
     2256
     2257lastpart = drivemntlist->entries - 1;
     2258for (partno = 0; partno < drivemntlist->entries; partno++) {
     2259    /* the 'atoi' thing is to make sure we don't try to resize _images_, whose formats will be numeric */
     2260    if (!atoi(drivemntlist->el[partno]->format)) {
     2261        new_size = (long long)((drivemntlist->el[partno]->size) * factor);
     2262    } else {
     2263        new_size = drivemntlist->el[partno]->size;
     2264    }
     2265
     2266    if (!strcmp(drivemntlist->el[partno]->mountpoint, "image")) {
     2267        log_msg(1, "Skipping %s (%s) because it's an image",
     2268                drivemntlist->el[partno]->device,
     2269                drivemntlist->el[partno]->mountpoint);
     2270    }
     2271    newsizL = new_size;
     2272
     2273    /* Do not apply the factor if partition was of negative size */
     2274    if (newsizL < 0LL) {
     2275        newsizL = drivemntlist->el[partno]->size;
     2276    }
     2277    totalsizL += newsizL;
     2278
     2279    log_to_screen("Changing %s from %lld KB to %lld KB", drivemntlist->el[partno]->device, drivemntlist->el[partno]->size, newsizL);
     2280    drivemntlist->el[partno]->size = newsizL;
     2281}
     2282// Ensures over-allocation alert and prompt for interactive mode does not happen
     2283if (totalsizL > current_size_of_drive) {
     2284    mr_asprintf(tmp, "Last partition size calculated would be over-allocated, reducing %s from %lld KB to %lld KB.", drivemntlist->el[lastpart]->device, drivemntlist->el[lastpart]->size, drivemntlist->el[lastpart]->size - (totalsizL - current_size_of_drive));
     2285    drivemntlist->el[drivemntlist->entries-1]->size -= (totalsizL - current_size_of_drive);
     2286} else if (totalsizL < current_size_of_drive) {
     2287    mr_asprintf(tmp, "Last partition size calculated would be under-allocated, increasing %s from %lld KB to %lld KB.",drivemntlist->el[lastpart]->device, drivemntlist->el[lastpart]->size, drivemntlist->el[lastpart]->size + (current_size_of_drive - totalsizL));
     2288    drivemntlist->el[drivemntlist->entries-1]->size += (current_size_of_drive - totalsizL);
     2289}
     2290log_to_screen(tmp);
     2291mr_free(tmp);
     2292log_to_screen("final_size = %lld MB", current_size_of_drive / 1024);
    24392293}
    24402294
     
    24462300 * @param mountlist The mountlist to resize the drives in.
    24472301 */
    2448 void resize_mountlist_proportionately_to_suit_new_drives(struct mountlist_itself
    2449                                                          *mountlist)
    2450 {
    2451     /** buffers *********************************************************/
    2452     struct list_of_disks *drivelist;
    2453 
    2454     /** int *************************************************************/
    2455     int driveno;
    2456 
    2457     /** end *************************************************************/
    2458 
    2459     drivelist = malloc(sizeof(struct list_of_disks));
    2460     assert(mountlist != NULL);
    2461 
    2462     if (g_mountlist_fname[0] == '\0') {
    2463         log_it("resize_mountlist_prop...() - warning - mountlist fname is blank");
    2464         log_it("That does NOT affect the functioning of this subroutine.");
    2465         log_it("--- Hugo, 2002/11/20");
    2466     }
    2467     log_it("Resizing mountlist");
    2468     make_list_of_drives_in_mountlist(mountlist, drivelist);
    2469     log_it("Back from MLoDiM");
    2470     for (driveno = 0; driveno < drivelist->entries; driveno++) {
    2471         resize_drive_proportionately_to_suit_new_drives(mountlist, drivelist->el[driveno].device);
    2472     }
    2473     log_to_screen("Mountlist adjusted to suit current hard drive(s)");
    2474     paranoid_free(drivelist);
     2302void resize_mountlist_proportionately_to_suit_new_drives(struct mountlist_itself *mountlist) {
     2303
     2304/** buffers *********************************************************/
     2305struct list_of_disks *drivelist;
     2306
     2307/** int *************************************************************/
     2308int driveno;
     2309
     2310/** end *************************************************************/
     2311
     2312drivelist = malloc(sizeof(struct list_of_disks));
     2313assert(mountlist != NULL);
     2314
     2315if (g_mountlist_fname[0] == '\0') {
     2316    log_it("resize_mountlist_prop...() - warning - mountlist fname is blank");
     2317    log_it("That does NOT affect the functioning of this subroutine.");
     2318    log_it("--- Hugo, 2002/11/20");
     2319}
     2320log_it("Resizing mountlist");
     2321make_list_of_drives_in_mountlist(mountlist, drivelist);
     2322log_it("Back from MLoDiM");
     2323for (driveno = 0; driveno < drivelist->entries; driveno++) {
     2324    resize_drive_proportionately_to_suit_new_drives(mountlist, drivelist->el[driveno].device);
     2325}
     2326log_to_screen("Mountlist adjusted to suit current hard drive(s)");
     2327paranoid_free(drivelist);
    24752328}
    24762329
     
    24832336 * @author Ralph Grewe
    24842337 */
    2485 void create_mountlist_for_drive(struct mountlist_itself *mountlist,
    2486                                 char *drive_name,
    2487                                 struct mountlist_reference *drivemntlist)
    2488 {
    2489     int partno;
    2490     char *tmp_drive_name, *c;
    2491 
    2492     assert(mountlist != NULL);
    2493     assert(drive_name != NULL);
    2494     assert(drivemntlist != NULL);
    2495 
    2496     log_msg(1, "Creating list of partitions for drive %s", drive_name);
    2497 
    2498     tmp_drive_name = strdup(drive_name);
    2499     if (!tmp_drive_name)
    2500         fatal_error("Out of memory");
    2501 
    2502     /* devfs devices? */
    2503     c = strrchr(tmp_drive_name, '/');
    2504     if (c && strncmp(c, "/disc", 5) == 0) {
    2505         /* yup its devfs, change the "disc" to "part" so the existing code works */
    2506         strcpy(c + 1, "part");
    2507     }
    2508     drivemntlist->entries = 0;
    2509     for (partno = 0; partno < mountlist->entries; partno++) {
    2510         if (strncmp
    2511             (mountlist->el[partno].device, tmp_drive_name,
    2512              strlen(tmp_drive_name)) == 0) {
    2513             drivemntlist->el[drivemntlist->entries] =
    2514                 &mountlist->el[partno];
    2515             drivemntlist->entries++;
    2516         }
    2517     }
    2518     if (tmp_drive_name)
    2519         free(tmp_drive_name);
     2338void create_mountlist_for_drive(struct mountlist_itself *mountlist, char *drive_name, struct mountlist_reference *drivemntlist) {
     2339
     2340int partno;
     2341char *tmp_drive_name, *c;
     2342
     2343assert(mountlist != NULL);
     2344assert(drive_name != NULL);
     2345assert(drivemntlist != NULL);
     2346
     2347log_msg(1, "Creating list of partitions for drive %s", drive_name);
     2348
     2349tmp_drive_name = strdup(drive_name);
     2350if (!tmp_drive_name)
     2351    fatal_error("Out of memory");
     2352
     2353/* devfs devices? */
     2354c = strrchr(tmp_drive_name, '/');
     2355if (c && strncmp(c, "/disc", 5) == 0) {
     2356    /* yup its devfs, change the "disc" to "part" so the existing code works */
     2357    strcpy(c + 1, "part");
     2358}
     2359drivemntlist->entries = 0;
     2360for (partno = 0; partno < mountlist->entries; partno++) {
     2361    if (strncmp(mountlist->el[partno].device, tmp_drive_name, strlen(tmp_drive_name)) == 0) {
     2362        drivemntlist->el[drivemntlist->entries] = &mountlist->el[partno];
     2363        drivemntlist->entries++;
     2364    }
     2365}
     2366if (tmp_drive_name)
     2367    free(tmp_drive_name);
    25202368}
    25212369
Note: See TracChangeset for help on using the changeset viewer.