Changeset 300 in MondoRescue for trunk/mondo/mondo/common/libmondo-fork.c


Ignore:
Timestamp:
Jan 11, 2006, 2:20:38 PM (18 years ago)
Author:
bcornec
Message:

merge -r295:299 $SVN_M/branches/2.06

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/mondo/mondo/common/libmondo-fork.c

    r171 r300  
    1 /* $Id$
    2   subroutines for handling forking/pthreads/etc.
     1/* libmondo-fork.c
     2   $Id$
     3
     4- subroutines for handling forking/pthreads/etc.
     5
     6
     701/20/2006
     8- replaced partimagehack with ntfsclone
     9
     1006/20/2004
     11- create fifo /var/log/partimagehack-debug.log and empty it
     12  to keep ramdisk from filling up
     13
     1404/13/2004
     15- >= should be <= g_loglevel
     16
     1711/15/2003
     18- changed a few []s to char*s
     19 
     2010/12
     21- rewrote partimagehack handling (multiple fifos, chunks, etc.)
     22
     2310/11
     24- partimagehack now has debug level of N (set in my-stuff.h)
     25
     2610/08
     27- call to partimagehack when restoring will now log errors to /var/log/....log
     28
     2910/06
     30- cleaned up logging a bit
     31
     3209/30
     33- line 735 - missing char* cmd in sprintf()
     34
     3509/28
     36- added run_external_binary_with_percentage_indicator()
     37- rewritten eval_call_to_make_ISO()
     38
     3909/18
     40- call mkstemp instead of mktemp
     41
     4209/13
     43- major NTFS hackage
     44
     4509/12
     46- paranoid_system("rm -f /tmp/ *PARTIMAGE*") before calling partimagehack
     47
     4809/11
     49- forward-ported unbroken feed_*_partimage() subroutines
     50  from early August 2003
     51
     5209/08
     53- detect & use partimagehack if it exists
     54
     5509/05
     56- finally finished partimagehack hack :)
     57
     5807/04
     59- added subroutines to wrap around partimagehack
     60
     6104/27
     62- don't echo (...res=%d...) at end of log_it()
     63  unnecessarily
     64- replace newtFinished() and newtInit() with
     65  newtSuspend() and newtResume()
     66
     6704/24
     68- added some assert()'s and log_OS_error()'s
     69
     7004/09
     71- cleaned up run_program_and_log_output()
     72
     7304/07
     74- cleaned up code a bit
     75- let run_program_and_log_output() accept -1 (only log if _no error_)
     76
     7701/02/2003
     78- in eval_call_to_make_ISO(), append output to MONDO_LOGFILE
     79  instead of a temporary stderr text file
     80
     8112/10
     82- patch by Heiko Schlittermann to handle % chars in issue.net
     83
     8411/18
     85- if mkisofs in eval_call_to_make_ISO() returns an error then return it,
     86  whether ISO was created or not
     87
     8810/30
     89- if mkisofs in eval_call_to_make_ISO() returns an error then find out if
     90  the output (ISO) file has been created; if it has then return 0 anyway
     91
     9208/01 - 09/30
     93- run_program_and_log_output() now takes boolean operator to specify
     94  whether it will log its activities in the event of _success_
     95- system() now includes 2>/dev/null
     96- enlarged some tmp[]'s
     97- added run_program_and_log_to_screen() and run_program_and_log_output()
     98
     9907/24
     100- created
    3101*/
    4102
     
    370468
    371469/**
    372  * Thread callback to run a command (partimage) in the background.
    373  * @param xfb A transfer block of @c char, containing:
    374  * - xfb:[0] A marker, should be set to 2. Decremented to 1 while the command is running and 0 when it's finished.
    375  * - xfb:[1] The command's return value, if xfb:[0] is 0.
    376  * - xfb+2:  A <tt>NULL</tt>-terminated string containing the command to be run.
    377  * @return NULL to pthread_join.
    378  */
    379 void *call_partimage_in_bkgd(void *xfb)
    380 {
    381     char *transfer_block;
    382     int retval = 0;
    383 
    384     g_buffer_pid = getpid();
    385     unlink("/tmp/null");
    386     log_msg(1, "starting");
    387     transfer_block = (char *) xfb;
    388     transfer_block[0]--;        // should now be 1
    389     retval = system(transfer_block + 2);
    390     if (retval) {
    391         log_OS_error("partimage returned an error");
    392     }
    393     transfer_block[1] = retval;
    394     transfer_block[0]--;        // should now be 0
    395     g_buffer_pid = 0;
    396     log_msg(1, "returning");
    397     pthread_exit(NULL);
    398 }
    399 
    400 
    401 /**
    402  * File to touch if we want partimage to wait for us.
    403  */
    404 #define PAUSE_PARTIMAGE_FNAME "/tmp/PAUSE-PARTIMAGE-FOR-MONDO"
    405 
    406 /**
    407470 * Apparently used. @bug This has a purpose, but what?
    408471 */
     
    410473#define PIMP_END_SZ "ENDENDEND0xBBC10xBBC2T231hc81h42vws89ff3kff9a82gv34r7fghbka"
    411474
    412 /**
    413  * Marker to start the next subvolume for Partimage.
    414  */
    415 #define NEXT_SUBVOL_PLEASE "I-grew-up-on-the-crime-side,-the-New-York-Times-side,-where-staying-alive-was-no-jive"
    416 
    417 /**
    418  * Marker to end the partimage file.
    419  */
    420 #define NO_MORE_SUBVOLS "On-second-hand,momma-bounced-on-old-man,-and-so-we-moved-to-Shaolin-Land."
     475
     476
    421477
    422478int copy_from_src_to_dest(FILE * f_orig, FILE * f_archived, char direction)
     
    559615}
    560616
    561 
    562617/**
    563  * Call partimage from @p input_device to @p output_fname.
    564  * @param input_device The device to read.
    565  * @param output_fname The file to write.
    566  * @return 0 for success, nonzero for failure.
    567  */
    568 int dynamically_create_pipes_and_copy_from_them_to_output_file(char
    569                                                                *input_device, char
    570                                                                *output_fname)
    571 {
    572     char *curr_fifo;
    573     char *prev_fifo = NULL;
    574     char *next_fifo;
    575     char *command;
    576     char *sz_call_to_partimage;
    577     int fifo_number = 0;
    578     struct stat buf;
    579     pthread_t partimage_thread;
    580     int res = 0;
    581     char *tmpstub;
    582     FILE *fout;
    583     FILE *fin;
    584     char *tmp;
    585 
    586     log_msg(1, "g_tmpfs_mountpt = %s", g_tmpfs_mountpt);
    587     if (g_tmpfs_mountpt && g_tmpfs_mountpt[0]
    588         && does_file_exist(g_tmpfs_mountpt)) {
    589         asprintf(&tmpstub, g_tmpfs_mountpt);
    590     } else {
    591         asprintf(&tmpstub, "/tmp");
    592     }
    593     paranoid_system("rm -f /tmp/*PARTIMAGE*");
    594     asprintf(&command, "rm -Rf %s/pih-fifo-*", tmpstub);
    595     paranoid_system(command);
    596     paranoid_free(command);
    597 
    598     asprintf(&tmp, "%s/pih-fifo-%ld", tmpstub, (long int) random());
    599     paranoid_free(tmpstub);
    600     tmpstub = tmp;
    601     paranoid_free(tmp);
    602 
    603     mkfifo(tmpstub, S_IRWXU | S_IRWXG); // never used, though...
    604     asprintf(&curr_fifo, "%s.%03d", tmpstub, fifo_number);
    605     asprintf(&next_fifo, "%s.%03d", tmpstub, fifo_number + 1);
    606     mkfifo(curr_fifo, S_IRWXU | S_IRWXG);
    607     mkfifo(next_fifo, S_IRWXU | S_IRWXG);   // make sure _next_ fifo already exists before we call partimage
    608     asprintf(&sz_call_to_partimage,
    609             "%c%cpartimagehack " PARTIMAGE_PARAMS
    610             " save %s %s > /tmp/stdout 2> /tmp/stderr", 2, 0, input_device,
    611             tmpstub);
    612     log_msg(5, "curr_fifo   = %s", curr_fifo);
    613     log_msg(5, "next_fifo   = %s", next_fifo);
    614     log_msg(5, "sz_call_to_partimage call is '%s'",
    615             sz_call_to_partimage + 2);
    616     if (!lstat(output_fname, &buf) && S_ISREG(buf.st_mode)) {
    617         log_msg(5, "Deleting %s", output_fname);
    618         unlink(output_fname);
    619     }
    620     if (!(fout = fopen(output_fname, "w"))) {
    621         fatal_error("Unable to openout to output_fname");
    622     }
    623     res =
    624         pthread_create(&partimage_thread, NULL, call_partimage_in_bkgd,
    625                        (void *) sz_call_to_partimage);
    626     if (res) {
    627         fatal_error("Failed to create thread to call partimage");
    628     }
    629     log_msg(1, "Running fore/back at same time");
    630     log_to_screen("Working with partimagehack...");
    631     while (sz_call_to_partimage[0] > 0) {
    632         asprintf(&tmp, "%s\n", NEXT_SUBVOL_PLEASE);
    633         if (fwrite(tmp, 1, 128, fout) != 128) {
    634             fatal_error("Cannot write interim block");
    635         }
    636         paranoid_free(tmp);
    637 
    638         log_msg(5, "fifo_number=%d", fifo_number);
    639         log_msg(4, "Cat'ting %s", curr_fifo);
    640         if (!(fin = fopen(curr_fifo, "r"))) {
    641             fatal_error("Unable to openin from fifo");
    642         }
    643         if (prev_fifo !=  NULL) {
    644             log_msg(5, "Deleting %s", prev_fifo);
    645             unlink(prev_fifo);      // just in case
    646             paranoid_free(prev_fifo);
    647         }
    648         copy_from_src_to_dest(fin, fout, 'w');
    649         paranoid_fclose(fin);
    650         fifo_number++;
    651 
    652         prev_fifo = curr_fifo;
    653         curr_fifo = next_fifo;
    654         log_msg(5, "Creating %s", next_fifo);
    655         asprintf(&next_fifo, "%s.%03d", tmpstub, fifo_number + 1);
    656         mkfifo(next_fifo, S_IRWXU | S_IRWXG);   // make sure _next_ fifo exists before we cat this one
    657         system("sync");
    658         sleep(5);
    659     }
    660     asprintf(&tmp, "%s\n", NO_MORE_SUBVOLS);
    661     if (fwrite(tmp, 1, 128, fout) != 128) {
    662         fatal_error("Cannot write interim block");
    663     }
    664     if (fwrite(tmp, 1, 128, fout) != 128) {
    665         fatal_error("Cannot write interim block");
    666     }
    667     if (fwrite(tmp, 1, 128, fout) != 128) {
    668         fatal_error("Cannot write interim block");
    669     }
    670     if (fwrite(tmp, 1, 128, fout) != 128) {
    671         fatal_error("Cannot write interim block");
    672     }
    673     paranoid_free(tmp);
    674     paranoid_fclose(fout);
    675     log_to_screen("Cleaning up after partimagehack...");
    676     log_msg(3, "Final fifo_number=%d", fifo_number);
    677     paranoid_system("sync");
    678     unlink(next_fifo);
    679     paranoid_free(next_fifo);
    680 
    681     unlink(curr_fifo);
    682     paranoid_free(curr_fifo);
    683 
    684     unlink(prev_fifo);
    685     paranoid_free(prev_fifo);
    686 
    687     log_to_screen("Finished cleaning up.");
    688 
    689 //  if (!lstat(sz_wait_for_this_file, &statbuf))
    690 //    { log_msg(3, "WARNING! %s was not processed.", sz_wait_for_this_file); }
    691     log_msg(2, "Waiting for pthread_join() to join.");
    692     pthread_join(partimage_thread, NULL);
    693     res = sz_call_to_partimage[1];
    694     paranoid_free(sz_call_to_partimage);
    695     log_msg(2, "pthread_join() joined OK.");
    696     log_msg(1, "Partimagehack(save) returned %d", res);
    697     unlink(tmpstub);
    698     paranoid_free(tmpstub);
    699 
    700     return (res);
    701 }
    702 
    703 
    704 /**
    705  * Feed @p input_device through partimage to @p output_fname.
     618 * Feed @p input_device through ntfsclone to @p output_fname.
    706619 * @param input_device The device to image.
    707620 * @param output_fname The file to write.
    708621 * @return 0 for success, nonzero for failure.
    709622 */
    710 int feed_into_partimage(char *input_device, char *output_fname)
     623int feed_into_ntfsprog(char *input_device, char *output_fname)
    711624{
    712625// BACKUP
    713     int res;
     626    int res = -1;
     627    char*command;
    714628
    715629    if (!does_file_exist(input_device)) {
    716630        fatal_error("input device does not exist");
    717631    }
    718     if (!find_home_of_exe("partimagehack")) {
    719         fatal_error("partimagehack not found");
    720     }
    721     res =
    722         dynamically_create_pipes_and_copy_from_them_to_output_file
    723         (input_device, output_fname);
     632    if ( !find_home_of_exe("ntfsclone")) {
     633        fatal_error("ntfsclone not found");
     634    }
     635    malloc_string(command);
     636    sprintf(command, "ntfsclone --force --save-image --overwrite %s %s", output_fname, input_device);
     637    res = run_program_and_log_output(command, 5);
     638    paranoid_free(command);
    724639    return (res);
    725640}
     
    871786}
    872787
    873 #define PIH_LOG "/var/log/partimage-debug.log"
    874788
    875789/**
    876  * Feed @p input_fifo through partimage (restore) to @p output_device.
    877  * @param input_fifo The partimage file to read.
     790 * Feed @p input_fifo through ntfsclone (restore) to @p output_device.
     791 * @param input_fifo The ntfsclone file to read.
    878792 * @param output_device Where to put the output.
    879  * @return The return value of partimagehack (0 for success).
    880  * @bug Probably unnecessary, as the partimage is just a sparse file. We could use @c dd to restore it.
     793 * @return The return value of ntfsclone (0 for success).
    881794 */
    882 int feed_outfrom_partimage(char *output_device, char *input_fifo)
     795int feed_outfrom_ntfsprog(char *output_device, char *input_fifo)
    883796{
    884797// RESTORE
    885     char *tmp;
    886     char *stuff;
    887     char *sz_call_to_partimage;
    888     pthread_t partimage_thread;
    889     int res;
    890     char *curr_fifo;
    891     char *prev_fifo = NULL;
    892     char *oldest_fifo = NULL;
    893     char *next_fifo;
    894     char *afternxt_fifo;
    895     int fifo_number = 0;
    896     char *tmpstub;
    897     FILE *fin;
    898     FILE *fout;
    899 
    900     log_msg(1, "output_device=%s", output_device);
    901     log_msg(1, "input_fifo=%s", input_fifo);
    902     asprintf(&tmpstub, "/tmp");
    903 
    904     log_msg(1, "tmpstub was %s", tmpstub);
    905     asprintf(&stuff, tmpstub);
    906     paranoid_free(tmpstub);
    907 
    908     asprintf(&tmpstub, "%s/pih-fifo-%ld", stuff, (long int) random());
    909     paranoid_free(stuff);
    910 
    911     log_msg(1, "tmpstub is now %s", tmpstub);
    912     unlink("/tmp/PARTIMAGEHACK-POSITION");
    913     unlink(PAUSE_PARTIMAGE_FNAME);
    914     paranoid_system("rm -f /tmp/*PARTIMAGE*");
    915     asprintf(&curr_fifo, "%s.%03d", tmpstub, fifo_number);
    916     asprintf(&next_fifo, "%s.%03d", tmpstub, fifo_number + 1);
    917     asprintf(&afternxt_fifo, "%s.%03d", tmpstub, fifo_number + 2);
    918     mkfifo(PIH_LOG, S_IRWXU | S_IRWXG);
    919     mkfifo(curr_fifo, S_IRWXU | S_IRWXG);
    920     mkfifo(next_fifo, S_IRWXU | S_IRWXG);   // make sure _next_ fifo already exists before we call partimage
    921     mkfifo(afternxt_fifo, S_IRWXU | S_IRWXG);
    922     system("cat " PIH_LOG " > /dev/null &");
    923     log_msg(3, "curr_fifo   = %s", curr_fifo);
    924     log_msg(3, "next_fifo   = %s", next_fifo);
    925     if (!does_file_exist(input_fifo)) {
    926         fatal_error("input fifo does not exist");
    927     }
    928     if (!(fin = fopen(input_fifo, "r"))) {
    929         fatal_error("Unable to openin from input_fifo");
    930     }
    931     if (!find_home_of_exe("partimagehack")) {
    932         fatal_error("partimagehack not found");
    933     }
    934     asprintf(&sz_call_to_partimage,
    935             "%c%cpartimagehack " PARTIMAGE_PARAMS
    936             " restore %s %s > /dev/null 2>> %s", 2, 0, output_device, curr_fifo,
    937             MONDO_LOGFILE);
    938     log_msg(1, "output_device = %s", output_device);
    939     log_msg(1, "curr_fifo = %s", curr_fifo);
    940     log_msg(1, "sz_call_to_partimage+2 = %s", sz_call_to_partimage + 2);
    941     res =
    942         pthread_create(&partimage_thread, NULL, call_partimage_in_bkgd,
    943                        (void *) sz_call_to_partimage);
    944     if (res) {
    945         fatal_error("Failed to create thread to call partimage");
    946     }
    947     log_msg(1, "Running fore/back at same time");
    948     log_msg(2, " Trying to openin %s", input_fifo);
    949     if (!does_file_exist(input_fifo)) {
    950         log_msg(2, "Warning - %s does not exist", input_fifo);
    951     }
    952     while (!does_file_exist("/tmp/PARTIMAGEHACK-POSITION")) {
    953         log_msg(6, "Waiting for partimagehack (restore) to start");
    954         sleep(1);
    955     }
    956 
    957     if (!(tmp = malloc(128))) {
    958         fatal_error("Failed to malloc() tmp");
    959     }
    960     while (sz_call_to_partimage[0] > 0) {
    961         if (fread(tmp, 1, 128, fin) != 128) {
    962             fatal_error("Cannot read introductory block");
    963         }
    964         if (strstr(tmp, NEXT_SUBVOL_PLEASE)) {
    965             log_msg(2, "Great. Next subvol coming up.");
    966         } else if (strstr(tmp, NO_MORE_SUBVOLS)) {
    967             log_msg(2, "Great. That was the last subvol.");
    968             break;
    969         } else {
    970             log_msg(2, "WTF is this? '%s'", tmp);
    971             fatal_error("Unknown interim block");
    972         }
    973         if (feof(fin)) {
    974             log_msg(1, "Eof(fin) detected. Breaking.");
    975             break;
    976         }
    977         log_msg(3, "Processing subvol %d", fifo_number);
    978         log_msg(5, "fifo_number=%d", fifo_number);
    979         if (!(fout = fopen(curr_fifo, "w"))) {
    980             fatal_error("Cannot openout to curr_fifo");
    981         }
    982         copy_from_src_to_dest(fout, fin, 'r');
    983         paranoid_fclose(fout);
    984         fifo_number++;
    985         if (oldest_fifo != NULL) {
    986             log_msg(6, "Deleting %s", oldest_fifo);
    987             unlink(oldest_fifo);    // just in case
    988             paranoid_free(oldest_fifo);
    989         }
    990         oldest_fifo = prev_fifo;
    991         prev_fifo = curr_fifo;
    992         curr_fifo = next_fifo;
    993         next_fifo = afternxt_fifo;
    994         asprintf(&afternxt_fifo, "%s.%03d", tmpstub, fifo_number + 2);
    995         log_msg(6, "Creating %s", afternxt_fifo);
    996         mkfifo(afternxt_fifo, S_IRWXU | S_IRWXG);   // make sure _next_ fifo already exists before we access current fifo
    997         fflush(fin);
    998 //      system("sync");
    999         usleep(1000L * 100L);
    1000     }
    1001     paranoid_free(tmp);
    1002     paranoid_free(tmpstub);
    1003 
    1004     paranoid_fclose(fin);
    1005     paranoid_system("sync");
    1006     log_msg(1, "Partimagehack has finished. Great. Fin-closing.");
    1007     log_msg(1, "Waiting for pthread_join");
    1008     pthread_join(partimage_thread, NULL);
    1009     res = sz_call_to_partimage[1];
    1010     paranoid_free(sz_call_to_partimage);
    1011 
    1012     log_msg(1, "Yay. Partimagehack (restore) returned %d", res);
    1013     unlink(prev_fifo);
    1014     paranoid_free(prev_fifo);
    1015 
    1016     unlink(curr_fifo);
    1017     paranoid_free(curr_fifo);
    1018 
    1019     unlink(next_fifo);
    1020     paranoid_free(next_fifo);
    1021 
    1022     unlink(afternxt_fifo);
    1023     paranoid_free(afternxt_fifo);
    1024 
    1025     unlink(PIH_LOG);
    1026     /* BERLIOS : pas de unlink(oldest_fifo) ??? */
    1027     paranoid_free(oldest_fifo);
    1028 
     798    int res = -1;
     799    char *command;
     800
     801    if ( !find_home_of_exe("ntfsclone")) {
     802        fatal_error("ntfsclone not found");
     803    }
     804    asprintf(&command, "ntfsclone --force --restore-image --overwrite %s %s", output_device, input_fifo);
     805    res = run_program_and_log_output(command, 5);
     806    paranoid_free(command);
    1029807    return (res);
    1030808}
Note: See TracChangeset for help on using the changeset viewer.