From 41f87db8a03d5045addda92934d8b497b9fccedb Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sun, 29 Jun 2025 15:17:27 +0000 Subject: [PATCH] transaction: Only create one jail to execute the scriptlets This should save us some time because we don't need to set up lots and lots of jails that are getting destroyed again very quickly. Signed-off-by: Michael Tremer --- src/pakfire/jail.h | 5 ++- src/pakfire/scriptlet.c | 16 +++++--- src/pakfire/scriptlet.h | 4 +- src/pakfire/transaction.c | 80 ++++++++++++++++++++++++--------------- 4 files changed, 65 insertions(+), 40 deletions(-) diff --git a/src/pakfire/jail.h b/src/pakfire/jail.h index 7c99909e..c29f6b38 100644 --- a/src/pakfire/jail.h +++ b/src/pakfire/jail.h @@ -21,6 +21,8 @@ #ifndef PAKFIRE_JAIL_H #define PAKFIRE_JAIL_H +#include + #include #include #include @@ -30,7 +32,8 @@ typedef struct pakfire_jail pakfire_jail; // Input callback -typedef pakfire_buffer_input_callback pakfire_jail_input_callback; +typedef ssize_t (*pakfire_jail_input_callback) + (pakfire_ctx* ctx, void* data, char* buffer, size_t length); // Output callback enum pakfire_jail_output_stream { diff --git a/src/pakfire/scriptlet.c b/src/pakfire/scriptlet.c index 05a4cd42..c4e5523a 100644 --- a/src/pakfire/scriptlet.c +++ b/src/pakfire/scriptlet.c @@ -178,12 +178,16 @@ static int pakfire_scriptlet_is_shell_script(pakfire_scriptlet* scriptlet) { return 0; } -int pakfire_scriptlet_execute(pakfire_scriptlet* scriptlet, pakfire_root* root) { - // Detect what kind of script this is and run it - if (pakfire_scriptlet_is_shell_script(scriptlet)) - return pakfire_jail_run_script(scriptlet->ctx, root, - scriptlet->data, scriptlet->size, NULL, NULL, 0); +int pakfire_scriptlet_execute(pakfire_scriptlet* self, pakfire_jail* jail) { + // We only support shell scripts + if (!pakfire_scriptlet_is_shell_script(self)) + goto UNSUPPORTED; - ERROR(scriptlet->ctx, "Scriptlet is of an unknown kind\n"); + // Execute the script + return pakfire_jail_execute_script(jail, self->data, self->size, + NULL, NULL, NULL, NULL, NULL, NULL); + +UNSUPPORTED: + ERROR(self->ctx, "Scriptlet is of an unknown kind\n"); return -ENOTSUP; } diff --git a/src/pakfire/scriptlet.h b/src/pakfire/scriptlet.h index 9e2400c9..133fa27e 100644 --- a/src/pakfire/scriptlet.h +++ b/src/pakfire/scriptlet.h @@ -22,7 +22,7 @@ #define PAKFIRE_SCRIPTLET_H #include -#include +#include extern const char* pakfire_scriptlet_types[13]; @@ -36,6 +36,6 @@ pakfire_scriptlet* pakfire_scriptlet_unref(pakfire_scriptlet* scriptlet); const char* pakfire_scriptlet_get_type(pakfire_scriptlet* scriptlet); const char* pakfire_scriptlet_get_data(pakfire_scriptlet* scriptlet, size_t* size); -int pakfire_scriptlet_execute(pakfire_scriptlet* scriptlet, pakfire_root* root); +int pakfire_scriptlet_execute(pakfire_scriptlet* scriptlet, pakfire_jail* jail); #endif /* PAKFIRE_SCRIPTLET_H */ diff --git a/src/pakfire/transaction.c b/src/pakfire/transaction.c index cd594694..86836e20 100644 --- a/src/pakfire/transaction.c +++ b/src/pakfire/transaction.c @@ -1300,9 +1300,10 @@ static int pakfire_transaction_verify(pakfire_transaction* transaction, return 0; } -static int pakfire_transaction_run_script(pakfire_transaction* transaction, - pakfire_db* db, const char* type, pakfire_package* pkg, pakfire_archive* archive) { +static int pakfire_transaction_run_script(pakfire_transaction* transaction, pakfire_db* db, + pakfire_jail* jail, const char* type, pakfire_package* pkg, pakfire_archive* archive) { pakfire_scriptlet* scriptlet = NULL; + int r = 0; // Fetch scriptlet from archive if possible if (archive) @@ -1312,14 +1313,23 @@ static int pakfire_transaction_run_script(pakfire_transaction* transaction, // Nothing to do if there are no scriptlets if (!scriptlet) - return 0; + goto ERROR; // Execute the scriptlet - pakfire_scriptlet_execute(scriptlet, transaction->root); + r = pakfire_scriptlet_execute(scriptlet, jail); + if (r < 0) { + ERROR(transaction->ctx, "Failed to execute the scriptlet: %s\n", strerror(-r)); + goto ERROR; + } - pakfire_scriptlet_unref(scriptlet); + // Reset any error codes + r = 0; - return 0; +ERROR: + if (scriptlet) + pakfire_scriptlet_unref(scriptlet); + + return r; } static int pakfire_transaction_extract(pakfire_transaction* transaction, @@ -1486,8 +1496,8 @@ static int pakfire_transaction_apply_systemd_tmpfiles( return 0; } -static int pakfire_transaction_run_step(pakfire_transaction* transaction, - pakfire_db* db, const enum pakfire_actions action, pakfire_package* pkg, pakfire_archive* archive) { +static int pakfire_transaction_run_step(pakfire_transaction* transaction, pakfire_db* db, + pakfire_jail* jail, const enum pakfire_actions action, pakfire_package* pkg, pakfire_archive* archive) { if (!pkg) { errno = EINVAL; return 1; @@ -1511,18 +1521,18 @@ static int pakfire_transaction_run_step(pakfire_transaction* transaction, switch (type) { case PAKFIRE_STEP_INSTALL: case PAKFIRE_STEP_REINSTALL: - r = pakfire_transaction_run_script(transaction, db, + r = pakfire_transaction_run_script(transaction, db, jail, "pretransin", pkg, archive); break; case PAKFIRE_STEP_UPGRADE: case PAKFIRE_STEP_DOWNGRADE: - r = pakfire_transaction_run_script(transaction, db, + r = pakfire_transaction_run_script(transaction, db, jail, "pretransup", pkg, archive); break; case PAKFIRE_STEP_ERASE: - r = pakfire_transaction_run_script(transaction, db, + r = pakfire_transaction_run_script(transaction, db, jail, "pretransun", pkg, archive); break; @@ -1539,18 +1549,18 @@ static int pakfire_transaction_run_step(pakfire_transaction* transaction, switch (type) { case PAKFIRE_STEP_INSTALL: case PAKFIRE_STEP_REINSTALL: - r = pakfire_transaction_run_script(transaction, db, + r = pakfire_transaction_run_script(transaction, db, jail, "posttransin", pkg, archive); break; case PAKFIRE_STEP_UPGRADE: case PAKFIRE_STEP_DOWNGRADE: - r = pakfire_transaction_run_script(transaction, db, + r = pakfire_transaction_run_script(transaction, db, jail, "posttransup", pkg, archive); break; case PAKFIRE_STEP_ERASE: - r = pakfire_transaction_run_script(transaction, db, + r = pakfire_transaction_run_script(transaction, db, jail, "posttransun", pkg, archive); break; @@ -1575,7 +1585,7 @@ static int pakfire_transaction_run_step(pakfire_transaction* transaction, if (r) break; - r = pakfire_transaction_run_script(transaction, db, + r = pakfire_transaction_run_script(transaction, db, jail, "prein", pkg, archive); if (r) break; @@ -1601,7 +1611,7 @@ static int pakfire_transaction_run_step(pakfire_transaction* transaction, if (r) break; - r = pakfire_transaction_run_script(transaction, db, + r = pakfire_transaction_run_script(transaction, db, jail, "postin", pkg, archive); break; @@ -1612,7 +1622,7 @@ static int pakfire_transaction_run_step(pakfire_transaction* transaction, if (r) break; - r = pakfire_transaction_run_script(transaction, db, + r = pakfire_transaction_run_script(transaction, db, jail, "preup", pkg, archive); if (r) break; @@ -1631,12 +1641,12 @@ static int pakfire_transaction_run_step(pakfire_transaction* transaction, if (r) break; - r = pakfire_transaction_run_script(transaction, db, + r = pakfire_transaction_run_script(transaction, db, jail, "postup", pkg, archive); break; case PAKFIRE_STEP_ERASE: - r = pakfire_transaction_run_script(transaction, db, + r = pakfire_transaction_run_script(transaction, db, jail, "preun", pkg, archive); if (r) break; @@ -1649,7 +1659,7 @@ static int pakfire_transaction_run_step(pakfire_transaction* transaction, if (r) break; - r = pakfire_transaction_run_script(transaction, db, + r = pakfire_transaction_run_script(transaction, db, jail, "postun", pkg, archive); break; @@ -1684,7 +1694,7 @@ static int pakfire_transaction_run_step(pakfire_transaction* transaction, } static int pakfire_transaction_run_steps(pakfire_transaction* transaction, - pakfire_db* db, enum pakfire_actions action) { + pakfire_db* db, pakfire_jail* jail, enum pakfire_actions action) { int r = 0; // Update status @@ -1713,7 +1723,7 @@ static int pakfire_transaction_run_steps(pakfire_transaction* transaction, // Walk through all steps for (unsigned int i = 0; i < transaction->num; i++) { - r = pakfire_transaction_run_step(transaction, db, action, + r = pakfire_transaction_run_step(transaction, db, jail, action, transaction->packages[i], transaction->archives[i]); // End loop if action was unsuccessful @@ -1847,36 +1857,42 @@ static int pakfire_usrmove(pakfire_ctx* ctx, pakfire_root* root) { static int pakfire_transaction_perform(pakfire_transaction* transaction) { pakfire_repo* repo = NULL; + pakfire_jail* jail = NULL; pakfire_db* db; size_t total_size = 0; int r; DEBUG(transaction->ctx, "Running Transaction %p\n", transaction); + // Create a new jail to execute any commands + r = pakfire_jail_create(&jail, transaction->ctx, transaction->root); + if (r < 0) + goto ERROR; + // Open all archives r = pakfire_transaction_open_archives(transaction, &total_size); - if (r) - return r; + if (r < 0) + goto ERROR; // Set the title r = pakfire_progress_set_title(transaction->progress, "%s", _("Installing Packages...")); if (r < 0) - return r; + goto ERROR; // Start the progress... r = pakfire_progress_start(transaction->progress, total_size); if (r < 0) - return r; + goto ERROR; // Open the database r = pakfire_db_open(&db, transaction->ctx, transaction->root, PAKFIRE_DB_READWRITE); if (r) { ERROR(transaction->ctx, "Could not open the database\n"); - return r; + goto ERROR; } // Verify steps - r = pakfire_transaction_run_steps(transaction, db, PAKFIRE_ACTION_VERIFY); + r = pakfire_transaction_run_steps(transaction, db, jail, PAKFIRE_ACTION_VERIFY); if (r) goto ERROR; @@ -1886,16 +1902,16 @@ static int pakfire_transaction_perform(pakfire_transaction* transaction) { goto ERROR; // Execute all pre transaction actions - r = pakfire_transaction_run_steps(transaction, db, PAKFIRE_ACTION_PRETRANS); + r = pakfire_transaction_run_steps(transaction, db, jail, PAKFIRE_ACTION_PRETRANS); if (r) goto ERROR; - r = pakfire_transaction_run_steps(transaction, db, PAKFIRE_ACTION_EXECUTE); + r = pakfire_transaction_run_steps(transaction, db, jail, PAKFIRE_ACTION_EXECUTE); if (r) goto ERROR; // Execute all post transaction actions - r = pakfire_transaction_run_steps(transaction, db, PAKFIRE_ACTION_POSTTRANS); + r = pakfire_transaction_run_steps(transaction, db, jail, PAKFIRE_ACTION_POSTTRANS); if (r) goto ERROR; @@ -1916,6 +1932,8 @@ static int pakfire_transaction_perform(pakfire_transaction* transaction) { r = pakfire_db_load(db, repo); ERROR: + if (jail) + pakfire_jail_unref(jail); if (repo) pakfire_repo_unref(repo); pakfire_db_unref(db); -- 2.47.3