int install_from_cwd(Options *op) { Package *p; CommandList *c; int ret; int ran_pre_install_hook = FALSE; HookScriptStatus res; static const char* edit_your_xf86config = "Please update your XF86Config or xorg.conf file as " "appropriate; see the file /usr/share/doc/" "NVIDIA_GLX-1.0/README.txt for details."; /* * validate the manifest file in the cwd, and process it, building * a Package struct */ if ((p = parse_manifest(op)) == NULL) goto failed; if (!op->x_files_packaged) { edit_your_xf86config = ""; } ui_set_title(op, "%s (%s)", p->description, p->version); /* * warn the user if "legacy" GPUs are installed in this system * and if no supported GPU is found, at all. */ check_for_nvidia_graphics_devices(op, p); /* check that we are not running any X server */ if (!check_for_running_x(op)) goto failed; /* make sure the kernel module is unloaded */ if (!check_for_unloaded_kernel_module(op)) goto failed; /* ask the user to accept the license */ if (!get_license_acceptance(op)) goto exit_install; ui_log(op, "Installing NVIDIA driver version %s.", p->version); /* * determine the current NVIDIA version (if any); ask the user if * they really want to overwrite the existing installation */ if (!check_for_existing_driver(op, p)) goto exit_install; /* * check to see if an alternate method of installation is already installed * or is available, but not installed; ask the user if they really want to * install anyway despite the presence/availability of an alternate install. */ if (!check_for_alternate_install(op)) goto exit_install; /* run the distro preinstall hook */ res = run_distro_hook(op, "pre-install"); if (res == HOOK_SCRIPT_FAIL) { if (ui_multiple_choice(op, CONTINUE_ABORT_CHOICES, NUM_CONTINUE_ABORT_CHOICES, CONTINUE_CHOICE, /* Default choice */ "The distribution-provided pre-install " "script failed! Are you sure you want " "to continue?") == ABORT_CHOICE) { goto failed; } } else if (res == HOOK_SCRIPT_SUCCESS) { if (ui_multiple_choice(op, CONTINUE_ABORT_CHOICES, NUM_CONTINUE_ABORT_CHOICES, CONTINUE_CHOICE, /* Default choice */ "The distribution-provided pre-install script " "completed successfully. If this is the first " "time you have run the installer, this script " "may have helped disable Nouveau, but a reboot " "may be required first. " "Would you like to continue, or would you " "prefer to abort installation to reboot the " "system?") == ABORT_CHOICE) { goto exit_install; } ran_pre_install_hook = TRUE; } /* fail if the nouveau driver is currently in use */ if (!check_for_nouveau(op)) goto failed; /* ask if we should install the UVM kernel module */ should_install_uvm(op, p); /* attempt to build the kernel modules for the target kernel */ if (!op->no_kernel_module) { if (!install_kernel_modules(op, p)) { goto failed; } } else { ui_warn(op, "You specified the '--no-kernel-module' command line " "option, nvidia-installer will not install a kernel " "module as part of this driver installation, and it will " "not remove existing NVIDIA kernel modules not part of " "an earlier NVIDIA driver installation. Please ensure " "that an NVIDIA kernel module matching this driver version " "is installed seperately."); /* no_kernel_module should imply no DKMS */ if (op->dkms) { ui_warn(op, "You have specified both the '--no-kernel-module' " "and the '--dkms' command line options. The '--dkms' " "option will be ignored."); op->dkms = FALSE; } } /* * if we are only installing the kernel module, then remove * everything else from the package; otherwise do some * OpenGL-specific stuff */ if (op->kernel_module_only) { remove_non_kernel_module_files_from_package(op, p); } else { /* ask for the XFree86 and OpenGL installation prefixes. */ if (!get_prefixes(op)) goto failed; /* ask if we should install the OpenGL header files */ should_install_opengl_headers(op, p); /* * select the appropriate TLS class, modifying the package as * necessary. */ select_tls_class(op, p); /* * if the package contains any libGL.la or .desktop files, * process them (perform some search and replacing so * that they reflect the correct installation path, etc) * and add them to the package list (files to be installed). */ process_libGL_la_files(op, p); process_dot_desktop_files(op, p); #if defined(NV_X86_64) /* * ask if we should install the 32bit compatibility files on * this machine. */ should_install_compat32_files(op, p); #endif /* NV_X86_64 */ } if (op->no_opengl_files) { remove_opengl_files_from_package(op, p); } /* * now that we have the installation prefixes, build the * destination for each file to be installed */ if (!set_destinations(op, p)) goto failed; /* * if we are installing OpenGL libraries, ensure that a symlink gets * installed to /usr/lib/libGL.so.1. add_libgl_abi_symlink() sets its own * destination, so it must be called after set_destinations(). */ if (!op->kernel_module_only && !op->no_opengl_files) { add_libgl_abi_symlink(op, p); } /* * uninstall the existing driver; this needs to be done before * building the command list. * * XXX if we uninstall now, then build the command list, and * then ask the user if they really want to execute the * command list, if the user decides not to execute the * command list, they'll be left with no driver installed. */ if (!op->kernel_module_only) { if (!run_existing_uninstaller(op)) goto failed; } if (!check_libglvnd_files(op, p)) { goto failed; } /* build a list of operations to execute to do the install */ if ((c = build_command_list(op, p)) == NULL) goto failed; /* call the ui to get approval for the list of commands */ if (!ui_approve_command_list(op, c, "%s", p->description)) { goto exit_install; } /* initialize the backup log file */ if (!op->kernel_module_only) { if (!init_backup(op, p)) goto failed; } /* execute the command list */ if (!do_install(op, p, c)) goto failed; /* Register, build, and install the module with DKMS, if requested */ if (op->dkms && !dkms_install_module(op, p->version, get_kernel_name(op))) goto failed; /* * Leave the RM loaded in case an X server with OutputClass-based driver * matching is being used. */ if (!op->no_kernel_module || op->dkms) { if (!load_kernel_module(op, p->kernel_modules[0].module_name)) { goto failed; } } /* run the distro postinstall script */ run_distro_hook(op, "post-install"); /* * check that everything is installed properly (post-install * sanity check) */ check_installed_files_from_package(op, p); if (!check_runtime_configuration(op, p)) goto failed; /* done */ if (op->kernel_module_only || op->no_nvidia_xconfig_question) { ui_message(op, "Installation of the kernel module for the %s " "(version %s) is now complete.", p->description, p->version); } else { /* ask the user if they would like to run nvidia-xconfig */ const char *msg = "Would you like to run the nvidia-xconfig utility " "to automatically update your X configuration file " "so that the NVIDIA X driver will be used when you " "restart X? Any pre-existing X configuration " "file will be backed up."; ret = run_nvidia_xconfig(op, FALSE, msg, op->run_nvidia_xconfig); if (ret) { ui_message(op, "Your X configuration file has been successfully " "updated. Installation of the %s (version: %s) is now " "complete.", p->description, p->version); } else { ui_message(op, "Installation of the %s (version: %s) is now " "complete. %s", p->description, p->version, edit_your_xf86config); } } free_package(p); return TRUE; failed: /* * something bad happened during installation; print an error * message and return FALSE */ if (op->logging) { ui_error(op, "Installation has failed. Please see the file '%s' " "for details. You may find suggestions on fixing " "installation problems in the README available on the " "Linux driver download page at www.nvidia.com.", op->log_file_name); } else { ui_error(op, "Installation has failed. You may find suggestions " "on fixing installation problems in the README available " "on the Linux driver download page at www.nvidia.com."); } if (ran_pre_install_hook) run_distro_hook(op, "failed-install"); /* fall through into exit_install... */ exit_install: /* * we are exiting installation; this can happen for reasons that * do not merit the error message (e.g., the user declined the * license agreement) */ free_package(p); return FALSE; } /* install_from_cwd() */
int copy_main (int argc, char **argv) { char source_a[PATH_MAX], source_b[PATH_MAX]; char dest_a[PATH_MAX], dest_b[PATH_MAX]; char *tmp; struct backup_info *info_b, *info_r; int opt, loop, thresh = 0, threshopt = 0; unsigned int varsize = 0, swapsize = 0; unsigned int bflags = BF_BACKUPVAR, rflags = 0; int quiet = 0; int bswap = 0; int expand = 0; int expandscale = 2; tivo_partition_direct (); while ((opt = getopt (argc, argv, "hqf:L:tTaspxr:v:S:lbBzE")) > 0) { switch (opt) { case 'q': quiet++; break; case 's': bflags |= BF_SHRINK; break; case 'E': bflags |= BF_TRUNCATED; break; case 'f': if (threshopt) { fprintf (stderr, "%s: -f and -%c cannot be used together\n", argv[0], threshopt); return 1; } threshopt = loop; thresh = strtoul (optarg, &tmp, 10); if (*tmp) { fprintf (stderr, "%s: Non integer argument to -f\n", argv[0]); return 1; } break; case 'L': if (threshopt) { fprintf (stderr, "%s: -l and -%c cannot be used together\n", argv[0], threshopt); return 1; } threshopt = loop; thresh = strtoul (optarg, &tmp, 10); thresh *= 1024 * 2; bflags |= BF_THRESHSIZE; if (*tmp) { fprintf (stderr, "%s: Non integer argument to -L\n", argv[0]); return 1; } break; case 't': bflags |= BF_THRESHTOT; break; case 'T': bflags |= BF_STREAMTOT; break; case 'a': if (threshopt) { fprintf (stderr, "%s: -a and -%c cannot be used together\n", argv[0], threshopt); return 1; } threshopt = loop; thresh = ~0; break; case 'v': bflags &= ~BF_BACKUPVAR; varsize = strtoul (optarg, &tmp, 10); varsize *= 1024 * 2; if (tmp && *tmp) { fprintf (stderr, "%s: Integer argument expected for -v.\n", argv[0]); return 1; } break; case 'S': swapsize = strtoul (optarg, &tmp, 10); swapsize *= 1024 * 2; if (tmp && *tmp) { fprintf (stderr, "%s: Integer argument expected for -s.\n", argv[0]); return 1; } break; case 'z': rflags |= RF_ZEROPART; break; case 'b': if (bswap != 0) { fprintf (stderr, "%s: Only one byte swapping option (-b/-B) allowed.\n", argv[0]); return 1; } bswap = -1; break; case 'B': if (bswap != 0) { fprintf (stderr, "%s: Only one byte swapping option (-b/-B) allowed.\n", argv[0]); return 1; } bswap = 1; break; case 'p': rflags |= RF_BALANCE; break; case 'l': rflags |= RF_NOFILL; break; case 'x': expand = 1; break; case 'r': expandscale = strtoul (optarg, &tmp, 10); if (tmp && *tmp) { fprintf (stderr, "%s: Integer argument expected for -r.\n", argv[0]); return 1; } if (expandscale < 0 || expandscale > 4) { fprintf (stderr, "%s: Scale value for -r must be in the range 0 to 4.\n", argv[0]); return 1; } break; default: copy_usage (argv[0]); return 1; } } // Split out the drive names source_a[0] = 0; source_b[0] = 0; dest_a[0] = 0; dest_b[0] = 0; if (argc - optind < 4) { if (optind < argc) { get_drives (argv[optind++], source_a, source_b); } if (optind < argc) { get_drives (argv[optind++], dest_a, dest_b); } } else { // Special case for convenience - 2 source and 2 target named strcpy (source_a, argv[optind++]); strcpy (source_b, argv[optind++]); strcpy (dest_a, argv[optind++]); strcpy (dest_b, argv[optind++]); } if (optind < argc || !*source_a || !*dest_a) { copy_usage (argv[0]); return 1; } if (expand > 0) rflags |= RF_NOFILL; info_b = init_backup (source_a, source_b, bflags); // Try to continue anyway despite error. if (bflags & BF_TRUNCATED && backup_has_error (info_b)) { backup_perror (info_b, "WARNING"); fprintf (stderr, "Attempting copy anyway\n"); backup_check_truncated_volume (info_b); if (info_b && backup_has_error (info_b)) { backup_perror (info_b, "Copy source"); return 1; } } if (info_b && backup_has_error (info_b)) { backup_perror (info_b, "Copy source"); fprintf (stderr, "To attempt copy anyway, try again with -E. -s is implied by -E.\n"); return 1; } info_r = init_restore (rflags); if (info_r && restore_has_error (info_r)) { restore_perror (info_r, "Copy target"); return 1; } if (!info_b || !info_r) { fprintf (stderr, "%s: Copy failed to start. Make sure you specified the right\ndevices, and that the drives are not locked.\n", argv[0]); return 1; } else { unsigned starttime; char buf[BUFSIZE]; unsigned int curcount = 0; int nread, nwrit; if (threshopt) backup_set_thresh (info_b, thresh); if (varsize) restore_set_varsize (info_r, varsize); if (swapsize) restore_set_swapsize (info_r, swapsize); if (bswap) restore_set_bswap (info_r, bswap); if (quiet < 2) fprintf (stderr, "Scanning source drive. Please wait a moment.\n"); if (backup_start (info_b) < 0) { if (backup_has_error (info_b)) backup_perror (info_b, "Copy source"); else fprintf (stderr, "Copy source failed.\n"); return 1; } // Fill the buffer up to start. Restore needs some information to bootstrap // the process. while (curcount < BUFSIZE && (nread = backup_read (info_b, buf, BUFSIZE - curcount)) > 0) { curcount += nread; } if (curcount < BUFSIZE) { if (backup_has_error (info_b)) backup_perror (info_b, "Copy source"); else fprintf (stderr, "Copy source failed.\n"); return 1; } nread = curcount; nwrit = restore_write (info_r, buf, nread); if (nwrit < 0) { if (restore_has_error (info_r)) restore_perror (info_r, "Copy target"); else fprintf (stderr, "Copy target failed.\n"); return 1; } if (restore_trydev (info_r, dest_a, dest_b) < 0) { if (restore_has_error (info_r)) restore_perror (info_r, "Copy target"); else fprintf (stderr, "Copy target failed.\n"); return 1; } if (restore_start (info_r) < 0) { if (restore_has_error (info_r)) restore_perror (info_r, "Copy target"); else fprintf (stderr, "Copy target failed.\n"); return 1; } if (restore_write (info_r, buf + nwrit, nread - nwrit) != nread - nwrit) { if (restore_has_error (info_r)) restore_perror (info_r, "Copy target"); else fprintf (stderr, "Copy target failed.\n"); return 1; } starttime = time (NULL); fprintf (stderr, "Starting copy\nSize: %d megabytes\n", info_r->nsectors / 2048); while ((curcount = backup_read (info_b, buf, BUFSIZE)) > 0) { unsigned int prcnt, compr; if (restore_write (info_r, buf, curcount) != curcount) { if (quiet < 1) fprintf (stderr, "\n"); if (restore_has_error (info_r)) restore_perror (info_r, "Copy source"); else fprintf (stderr, "Copy source failed.\n"); return 1; } prcnt = get_percent (info_r->cursector, info_r->nsectors); if (quiet < 1) { unsigned timedelta = time(NULL) - starttime; fprintf (stderr, "\rCopying %d of %d mb (%d.%02d%%)", info_r->cursector / 2048, info_r->nsectors / 2048, prcnt / 100, prcnt % 100); if (prcnt > 100 && timedelta > 15) { unsigned ETA = timedelta * (10000 - prcnt) / prcnt; fprintf (stderr, " %d mb/sec (ETA %d:%02d:%02d)", info_r->cursector / timedelta / 2048, ETA / 3600, ETA / 60 % 60, ETA % 60); } } } if (quiet < 1) fprintf (stderr, "\n"); if (backup_has_error (info_b)) { backup_perror (info_b, "Copy source"); return 1; } if (restore_has_error (info_r)) { restore_perror (info_r, "Copy target"); return 1; } } if (backup_finish (info_b) < 0) { if (backup_has_error (info_b)) backup_perror (info_b, "Copy source"); else fprintf (stderr, "Copy source failed.\n"); return 1; } if (info_b->back_flags & BF_TRUNCATED) { fprintf (stderr, "***WARNING***\nCopy was made of an incomplete volume. While the copy succeeded,\nit is possible there was some required data missing. Verify your copy.\n"); } if (quiet < 2) fprintf (stderr, "Cleaning up target. Please wait a moment.\n"); if (restore_finish (info_r) < 0) { if (restore_has_error (info_r)) restore_perror (info_r, "Copy target"); else fprintf (stderr, "Copy target failed.\n"); return 1; } if (quiet < 2) fprintf (stderr, "Copy done!\n"); if (expand > 0) { int blocksize = 0x800; struct mfs_handle *mfshnd; expand = 0; mfshnd = mfs_init (dest_a, dest_b, O_RDWR); if (!mfshnd) { fprintf (stderr, "Drive expansion failed.\n"); return 1; } if (mfs_has_error (mfshnd)) { mfs_perror (mfshnd, "Target expand"); return 1; } while (expandscale-- > 0) blocksize *= 2; if (tivo_partition_largest_free (dest_a) > 1024 * 1024 * 2) { if (expand_drive (mfshnd, "/dev/hda", dest_a, blocksize) < 0) { if (mfs_has_error (mfshnd)) mfs_perror (mfshnd, "Expand drive A"); else fprintf (stderr, "Drive A expansion failed.\n"); return 1; } expand++; } if (dest_b[0] && tivo_partition_largest_free (dest_b) > 1024 * 1024 * 2) { if (expand_drive (mfshnd, "/dev/hdb", dest_b, blocksize) < 0) { if (mfs_has_error (mfshnd)) mfs_perror (mfshnd, "Expand drive B"); else fprintf (stderr, "Drive B expansion failed.\n"); return 1; } expand++; } if (!expand) { fprintf (stderr, "Not enough extra space to expand on A drive%s.\n", dest_b[0]? " or B drive": ""); } } return 0; }