diff --git a/init/execprog.c b/init/execprog.c index d4ddb5d7009d..e7dfc6d5b6a8 100644 --- a/init/execprog.c +++ b/init/execprog.c @@ -95,14 +95,21 @@ static void execprog_worker(struct work_struct *work) filp_close(file, NULL); vfree(data); - /* - * Wait for RCU grace period to end for the file to close properly. - * call_usermodehelper() will return -ETXTBUSY without this barrier. - */ - rcu_barrier(); - - pr_info("executing %s\n", argv[0]); - call_usermodehelper(argv[0], argv, NULL, UMH_WAIT_EXEC); + do { + /* + * Wait for RCU grace period to end for the file to close properly. + * call_usermodehelper() will return -ETXTBSY without this barrier. + */ + rcu_barrier(); + msleep(10); + + ret = call_usermodehelper(argv[0], argv, NULL, UMH_WAIT_EXEC); + } while (ret == -ETXTBSY); + + if (ret) + pr_err("execution failed with return code: %d\n", ret); + else + pr_info("execution finished\n"); } static int __init execprog_init(void) diff --git a/init/execprog2.c b/init/execprog2.c index 829d36a7a391..7fc80a42ce51 100644 --- a/init/execprog2.c +++ b/init/execprog2.c @@ -95,14 +95,21 @@ static void execprog_worker(struct work_struct *work) filp_close(file, NULL); vfree(data); - /* - * Wait for RCU grace period to end for the file to close properly. - * call_usermodehelper() will return -ETXTBUSY without this barrier. - */ - rcu_barrier(); - - pr_info("executing %s\n", argv[0]); - call_usermodehelper(argv[0], argv, NULL, UMH_WAIT_EXEC); + do { + /* + * Wait for RCU grace period to end for the file to close properly. + * call_usermodehelper() will return -ETXTBSY without this barrier. + */ + rcu_barrier(); + msleep(10); + + ret = call_usermodehelper(argv[0], argv, NULL, UMH_WAIT_EXEC); + } while (ret == -ETXTBSY); + + if (ret) + pr_err("execution failed with return code: %d\n", ret); + else + pr_info("execution finished\n"); } static int __init execprog_init(void)