]> git.ipfire.org Git - pakfire.git/commitdiff
transaction: Only create one jail to execute the scriptlets
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 29 Jun 2025 15:17:27 +0000 (15:17 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 29 Jun 2025 15:17:27 +0000 (15:17 +0000)
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 <michael.tremer@ipfire.org>
src/pakfire/jail.h
src/pakfire/scriptlet.c
src/pakfire/scriptlet.h
src/pakfire/transaction.c

index 7c99909eaab9dacaf14dec9e4ad26dcebf5a6f2f..c29f6b382de0f7bb74a466b5bc181572546bf1c0 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef PAKFIRE_JAIL_H
 #define PAKFIRE_JAIL_H
 
+#include <limits.h>
+
 #include <pakfire/buffer.h>
 #include <pakfire/cgroup.h>
 #include <pakfire/ctx.h>
@@ -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 {
index 05a4cd4229478ba5b5fda6dc6964a68bec03367a..c4e5523ab9cb862cd4c94a9707668d77c0abf928 100644 (file)
@@ -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;
 }
index 9e2400c9814dc20be10350f913dfdb7537575d6d..133fa27e0c2765f4d5d0275b010e3cbd86508efa 100644 (file)
@@ -22,7 +22,7 @@
 #define PAKFIRE_SCRIPTLET_H
 
 #include <pakfire/ctx.h>
-#include <pakfire/root.h>
+#include <pakfire/jail.h>
 
 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 */
index cd5946947f5a5d15f8bb88455ae4530adc3ae29e..86836e203822a7a16c81f380c63bf9a4e2cc63a0 100644 (file)
@@ -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);