diff -r 810d9ba06afd -r 891991677a7f src/main.c --- a/src/main.c Wed Feb 01 12:49:13 2012 +0000 +++ b/src/main.c Thu Feb 09 20:45:27 2012 +0000 @@ -1,7 +1,7 @@ /* * Copyright (C) 2008 Kristian Høgsberg * Copyright (C) 2008 Red Hat, Inc - * Copyright (C) 2009, 2011 J. Ali Harlow + * Copyright (C) 2009, 2011-2012 J. Ali Harlow * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -48,18 +48,16 @@ #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -enum update_pass_type { - UPDATE_PASS_PRE_REMOVE, - UPDATE_PASS_MAIN, - UPDATE_PASS_POST_INSTALL, -}; - static int update_packages(struct razor_transaction *trans, struct razor_install_iterator *ii, struct razor_set *system, struct razor_set *next, struct razor_atomic *atomic, struct razor_relocations *relocations, - enum update_pass_type stage); + enum razor_stage_type stage); +static int +update_system(const char *install_root, struct razor_relocations *relocations, + struct razor_transaction *trans, struct razor_set *system, + struct razor_set *next, const char *verb); static struct razor_package_iterator * create_iterator_from_argv(struct razor_set *set, int argc, const char *argv[]) @@ -619,24 +617,22 @@ static int command_remove(int argc, const char *argv[]) { - struct razor_root *root; struct razor_set *system, *upstream, *next; struct razor_transaction *trans; struct razor_atomic *atomic; - struct razor_install_iterator *ii; int i, retval; atomic = razor_atomic_open("Remove packages"); - root = razor_root_open(install_root, atomic); - system = razor_set_ref(razor_root_get_system_set(root)); + system = razor_root_open_read_only(install_root, atomic); if (system == NULL) { fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); - razor_root_close(root); razor_atomic_destroy(atomic); return 1; } + razor_atomic_destroy(atomic); + upstream = razor_set_create_without_root(); trans = razor_transaction_create(system, upstream); razor_set_unref(upstream); @@ -645,8 +641,6 @@ fprintf(stderr, "no match for %s\n", argv[i]); razor_transaction_destroy(trans); razor_set_unref(system); - razor_root_close(root); - razor_atomic_destroy(atomic); return 1; } } @@ -656,33 +650,15 @@ if (retval) { razor_transaction_destroy(trans); razor_set_unref(system); - razor_root_close(root); - razor_atomic_destroy(atomic); return 1; } next = razor_transaction_commit(trans); - ii = razor_set_create_install_iterator(system, next); - retval = update_packages(trans, ii, system, next, atomic, NULL, - UPDATE_PASS_PRE_REMOVE); - if (retval) - fprintf(stderr, "Remove aborted\n"); - else { - update_packages(trans, ii, system, next, atomic, NULL, - UPDATE_PASS_MAIN); - razor_root_update(root, next); + retval = update_system(install_root, NULL, trans, system, next, + "Remove"); - (void)razor_root_commit(root); - retval = razor_atomic_commit(atomic); - if (retval) - fprintf(stderr, "%s\n", - razor_atomic_get_error_msg(atomic)); - } - - razor_install_iterator_destroy(ii); razor_transaction_destroy(trans); - razor_atomic_destroy(atomic); razor_set_unref(system); razor_set_unref(next); @@ -826,7 +802,7 @@ ii = razor_set_create_install_iterator(system, next); while (razor_install_iterator_next(ii, &package, &action, &count)) { - if (action == RAZOR_INSTALL_ACTION_REMOVE) + if (action != RAZOR_INSTALL_ACTION_ADD) continue; razor_package_get_details(next, package, @@ -989,108 +965,118 @@ } /* - * In the most general case, there should be three passes: - * - * 1) For each package to be removed, run %preun - * - * 2) For each package: - * If the package is to be installed, run %pre - * Update the files on disk - * If the package has been removed, run %postun - * - * 3) For each packge installed, run %post - * - * This guarantees that: - * a) Save where dependency loops make it impossible, at the time - * %pre is run, all required packages are installed (although - * their %post script may not have been run). We should support - * Requires(%pre) to allow packagers to describe their requirements - * more accurately and avoid unnecessary dependency loops. - * b) At the time %preun is run, all required packages are installed. - * Supporting Requires(%preun) would make this more complicated - * since we might have to install a package in order to remove - * another one. For now, treating Requires(%preun) as Requires - * seems more sensible. - * c) At the time %post is run, all required packages are installed. - * Supporting Requires(%post) would allow us to remove a package - * that was only needed to install another, but there seems no - * obvious advantage. - * d) Save where dependency loops make it impossible, at the time - * %postun is run, all required packages are installed. Again, - * we should support Requires(%postun) to avoid unnecessary - * dependency loops. - * - * Notes: - * rpm treats %pre and %preun script failures as fatal errors - * and %post and %postun failures as warnings. + * Returns 0 on success, -1 on failure and 1 if a RAZOR_INSTALL_ACTION_COMMIT + * is met (in which case the action is consumed). */ static int update_packages(struct razor_transaction *trans, struct razor_install_iterator *ii, struct razor_set *system, struct razor_set *next, struct razor_atomic *atomic, struct razor_relocations *relocations, - enum update_pass_type pass) + enum razor_stage_type stage) { struct razor_package *package; enum razor_install_action action; int retval = 0, count; - enum razor_stage_type remove_stage, add_stage; - - switch (pass) { - case UPDATE_PASS_PRE_REMOVE: - add_stage = 0; - remove_stage = RAZOR_STAGE_SCRIPTS_PRE; - break; - case UPDATE_PASS_MAIN: - add_stage = RAZOR_STAGE_SCRIPTS_PRE | RAZOR_STAGE_FILES; - remove_stage = RAZOR_STAGE_FILES | RAZOR_STAGE_SCRIPTS_POST; - break; - case UPDATE_PASS_POST_INSTALL: - add_stage = RAZOR_STAGE_SCRIPTS_POST; - remove_stage = 0; - break; - } - - razor_install_iterator_rewind(ii); while (!retval && razor_install_iterator_next(ii, &package, &action, &count)) { - if (action == RAZOR_INSTALL_ACTION_ADD && add_stage) - retval = install_package(trans, next, atomic, package, - relocations, count, add_stage); - else if (action == RAZOR_INSTALL_ACTION_REMOVE && remove_stage) - retval = razor_package_remove(system, next, atomic, - package, install_root, - count, remove_stage); + if (action == RAZOR_INSTALL_ACTION_ADD) { + if (install_package(trans, next, atomic, package, + relocations, count, stage)) + retval = -1; + } else if (action == RAZOR_INSTALL_ACTION_REMOVE) { + if (razor_package_remove(system, next, atomic, package, + install_root, count, stage)) + retval = -1; + } else if (action == RAZOR_INSTALL_ACTION_COMMIT) + retval = 1; } return retval; } static int +update_system(const char *install_root, struct razor_relocations *relocations, + struct razor_transaction *trans, struct razor_set *system, + struct razor_set *next, const char *verb) +{ + struct razor_root *root; + struct razor_set *set; + struct razor_atomic *atomic; + struct razor_install_iterator *ii; + int r, retval = 0; + char *description; + size_t pos; + + description = razor_concat(verb, " packages", NULL); + + ii = razor_set_create_install_iterator(system, next); + + do { + pos = razor_install_iterator_tell(ii); + + atomic = razor_atomic_open(description); + + root = razor_root_open(install_root, atomic); + if (root == NULL) { + fprintf(stderr, "%s\n", + razor_atomic_get_error_msg(atomic)); + razor_atomic_destroy(atomic); + retval = 1; + break; + } + + r = update_packages(trans, ii, system, next, atomic, + relocations, RAZOR_STAGE_SCRIPTS_PRE); + if (r < 0) { + fprintf(stderr, "%s aborted\n", verb); + razor_atomic_destroy(atomic); + retval = r; + } else { + razor_install_iterator_seek(ii, pos); + r = update_packages(trans, ii, system, next, atomic, + relocations, RAZOR_STAGE_FILES); + + if (r == 1) { + set = razor_install_iterator_commit_set(ii); + razor_root_update(root, set); + razor_set_unref(set); + } else if (r == 0) + razor_root_update(root, next); + + (void)razor_root_commit(root); + retval = razor_atomic_commit(atomic); + if (retval) { + fprintf(stderr, "%s\n", + razor_atomic_get_error_msg(atomic)); + razor_atomic_destroy(atomic); + } else { + razor_install_iterator_seek(ii, pos); + update_packages(trans, ii, system, next, + atomic, relocations, + RAZOR_STAGE_SCRIPTS_POST); + } + } + + razor_atomic_destroy(atomic); + } while(!retval && r == 1); + + free(description); + + return retval; +} + +static int command_install_or_update(int argc, const char *argv[], int do_update) { - struct razor_root *root; struct razor_relocations *relocations=NULL; struct razor_set *system, *upstream, *next, *set; struct razor_transaction *trans; struct razor_atomic *atomic; - struct razor_install_iterator *ii; int i, retval, len, dependencies = 1; char *oldpath; - if (do_update) - atomic = razor_atomic_open("Update packages"); - else - atomic = razor_atomic_open("Install packages"); - - root = razor_root_open(install_root, atomic); - if (root == NULL) { - fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); - razor_atomic_destroy(atomic); - return 1; - } - for (i = 0; i < argc; i++) { if (strcmp(argv[i], "--no-dependencies") == 0) dependencies = 0; @@ -1119,10 +1105,14 @@ break; } + if (do_update) + atomic = razor_atomic_open("Update packages"); + else + atomic = razor_atomic_open("Install packages"); + upstream = razor_set_open(rawhide_repo_filename, atomic); if (upstream == NULL) { fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); - razor_root_close(root); razor_atomic_destroy(atomic); return 1; } @@ -1132,7 +1122,6 @@ if (set == NULL) { fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); - razor_root_close(root); razor_atomic_destroy(atomic); razor_set_unref(upstream); return 1; @@ -1141,7 +1130,7 @@ upstream = set; } - system = razor_set_ref(razor_root_get_system_set(root)); + system = razor_root_open_read_only(install_root, atomic); trans = razor_transaction_create(system, upstream); @@ -1156,7 +1145,6 @@ razor_transaction_destroy(trans); razor_set_unref(upstream); razor_set_unref(system); - razor_root_close(root); razor_atomic_destroy(atomic); return 1; } @@ -1168,23 +1156,24 @@ razor_transaction_destroy(trans); razor_set_unref(upstream); razor_set_unref(system); - razor_root_close(root); razor_atomic_destroy(atomic); return 1; } } if (razor_atomic_create_dir(atomic, "rpms", - S_IRWXU | S_IRWXG | S_IRWXO)) { + S_IRWXU | S_IRWXG | S_IRWXO) || + razor_atomic_commit(atomic)) { fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic)); razor_transaction_destroy(trans); razor_set_unref(upstream); razor_set_unref(system); - razor_root_close(root); razor_atomic_destroy(atomic); return 1; } + razor_atomic_destroy(atomic); + next = razor_transaction_commit(trans); if (download_packages(system, next) < 0) { @@ -1192,43 +1181,18 @@ razor_transaction_destroy(trans); razor_set_unref(upstream); razor_set_unref(system); - razor_root_close(root); razor_atomic_destroy(atomic); return 1; } - ii = razor_set_create_install_iterator(system, next); + retval = update_system(install_root, relocations, trans, system, next, + do_update ? "Update" : "Install"); - retval = update_packages(trans, ii, system, next, atomic, relocations, - UPDATE_PASS_PRE_REMOVE); - if (retval) - fprintf(stderr, "%s aborted\n", - do_update ? "Update" : "Install"); - else { - update_packages(trans, ii, system, next, atomic, relocations, - UPDATE_PASS_MAIN); - - razor_root_update(root, next); - - razor_set_unref(upstream); - - (void)razor_root_commit(root); - retval = razor_atomic_commit(atomic); - if (retval) - fprintf(stderr, "%s\n", - razor_atomic_get_error_msg(atomic)); - else - (void)update_packages(trans, ii, system, next, atomic, - relocations, - UPDATE_PASS_POST_INSTALL); - } + razor_set_unref(upstream); razor_transaction_destroy(trans); if (relocations) razor_relocations_destroy(relocations); - razor_install_iterator_destroy(ii); - - razor_atomic_destroy(atomic); razor_set_unref(next); razor_set_unref(system);