Changeset 300 in MondoRescue for trunk/mondo/mondo/common/libmondo-fork.c
- Timestamp:
- Jan 11, 2006, 2:20:38 PM (18 years ago)
- 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 7 01/20/2006 8 - replaced partimagehack with ntfsclone 9 10 06/20/2004 11 - create fifo /var/log/partimagehack-debug.log and empty it 12 to keep ramdisk from filling up 13 14 04/13/2004 15 - >= should be <= g_loglevel 16 17 11/15/2003 18 - changed a few []s to char*s 19 20 10/12 21 - rewrote partimagehack handling (multiple fifos, chunks, etc.) 22 23 10/11 24 - partimagehack now has debug level of N (set in my-stuff.h) 25 26 10/08 27 - call to partimagehack when restoring will now log errors to /var/log/....log 28 29 10/06 30 - cleaned up logging a bit 31 32 09/30 33 - line 735 - missing char* cmd in sprintf() 34 35 09/28 36 - added run_external_binary_with_percentage_indicator() 37 - rewritten eval_call_to_make_ISO() 38 39 09/18 40 - call mkstemp instead of mktemp 41 42 09/13 43 - major NTFS hackage 44 45 09/12 46 - paranoid_system("rm -f /tmp/ *PARTIMAGE*") before calling partimagehack 47 48 09/11 49 - forward-ported unbroken feed_*_partimage() subroutines 50 from early August 2003 51 52 09/08 53 - detect & use partimagehack if it exists 54 55 09/05 56 - finally finished partimagehack hack :) 57 58 07/04 59 - added subroutines to wrap around partimagehack 60 61 04/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 67 04/24 68 - added some assert()'s and log_OS_error()'s 69 70 04/09 71 - cleaned up run_program_and_log_output() 72 73 04/07 74 - cleaned up code a bit 75 - let run_program_and_log_output() accept -1 (only log if _no error_) 76 77 01/02/2003 78 - in eval_call_to_make_ISO(), append output to MONDO_LOGFILE 79 instead of a temporary stderr text file 80 81 12/10 82 - patch by Heiko Schlittermann to handle % chars in issue.net 83 84 11/18 85 - if mkisofs in eval_call_to_make_ISO() returns an error then return it, 86 whether ISO was created or not 87 88 10/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 92 08/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 99 07/24 100 - created 3 101 */ 4 102 … … 370 468 371 469 /** 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 1389 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 0395 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 /**407 470 * Apparently used. @bug This has a purpose, but what? 408 471 */ … … 410 473 #define PIMP_END_SZ "ENDENDEND0xBBC10xBBC2T231hc81h42vws89ff3kff9a82gv34r7fghbka" 411 474 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 421 477 422 478 int copy_from_src_to_dest(FILE * f_orig, FILE * f_archived, char direction) … … 559 615 } 560 616 561 562 617 /** 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. 706 619 * @param input_device The device to image. 707 620 * @param output_fname The file to write. 708 621 * @return 0 for success, nonzero for failure. 709 622 */ 710 int feed_into_ partimage(char *input_device, char *output_fname)623 int feed_into_ntfsprog(char *input_device, char *output_fname) 711 624 { 712 625 // BACKUP 713 int res; 626 int res = -1; 627 char*command; 714 628 715 629 if (!does_file_exist(input_device)) { 716 630 fatal_error("input device does not exist"); 717 631 } 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); 724 639 return (res); 725 640 } … … 871 786 } 872 787 873 #define PIH_LOG "/var/log/partimage-debug.log"874 788 875 789 /** 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. 878 792 * @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). 881 794 */ 882 int feed_outfrom_ partimage(char *output_device, char *input_fifo)795 int feed_outfrom_ntfsprog(char *output_device, char *input_fifo) 883 796 { 884 797 // 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); 1029 807 return (res); 1030 808 }
Note:
See TracChangeset
for help on using the changeset viewer.