.\" -*- coding: UTF-8 -*- .\" Copyright 2019, Michael Kerrisk .\" Copyright, the authors of the Linux man-pages project .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH pivot_root 2 "8 فبراير 2026" "صفحات دليل لينكس 6.18" .SH الاسم pivot_root \- تغيير نقطة الوصل الجذرية .SH المكتبة مكتبة سي المعيارية (\fIlibc\fP،\ \fI\-lc\fP) .SH موجز .nf \fB#include \fP /* تعريف ثوابت \fBSYS_*\fP */ \fB#include \fP .P \fBint syscall(SYS_pivot_root, const char *\fP\fInew_root\fP\fB, const char *\fP\fIput_old\fP\fB);\fP .fi .P \fIملاحظة\fP: لا توفر glibc غلافًا لـ \fBpivot_root\fP()، مما يستلزم استخدام \fBsyscall\fP(2). .SH الوصف يغير \fBpivot_root\fP() نقطة الوصل الجذرية في مساحة أسماء الوصل الخاصة بالعملية المستدعية. بشكل أدق، ينقل نقطة الوصل الجذرية إلى الدليل \fIput_old\fP ويجعل \fInew_root\fP نقطة الوصل الجذرية الجديدة. يجب أن تمتلك العملية المستدعية إمكانية \fBCAP_SYS_ADMIN\fP في مساحة أسماء المستخدم التي تمتلك مساحة أسماء الوصل الخاصة بالمستدعي. .P يغير \fBpivot_root\fP() الدليل الجذري ودليل العمل الحالي لكل عملية أو خيط في نفس مساحة أسماء الوصل إلى \fInew_root\fP إذا كانا يشيران إلى الدليل الجذري القديم. (انظر أيضًا الملاحظات.) من ناحية أخرى، لا يغير \fBpivot_root\fP() دليل العمل الحالي للمستدعي (إلا إذا كان على الدليل الجذري القديم)، وبالتالي يجب أن يتبعه استدعاء \fIchdir("/")\fP. .P تنطبق القيود التالية: .IP \[bu] 3 يجب أن يكون \fInew_root\fP و \fIput_old\fP دليلين. .IP \[bu] يجب ألا يكون \fInew_root\fP و \fIput_old\fP على نفس نقطة الوصل مثل الجذر الحالي. .IP \[bu] يجب أن يكون \fIput_old\fP عند أو أسفل \fInew_root\fP؛ أي أن إضافة عدد غير سالب من اللواحق \[dq]\fI/..\&\fP\[dq] إلى اسم المسار المشار إليه بواسطة \fIput_old\fP يجب أن ينتج نفس الدليل مثل \fInew_root\fP. .IP \[bu] يجب أن يكون \fInew_root\fP مسارًا إلى نقطة وصل، لكن لا يمكن أن يكون \fI\[dq]/\[dq]\fP. يمكن تحويل مسار ليس بالفعل نقطة وصل إلى واحدة عن طريق وصل ربط المسار على نفسه. .IP \[bu] يجب ألا يكون نوع الانتشار لنقطة الوصل الأم لـ \fInew_root\fP ونقطة الوصل الأم للدليل الجذري الحالي \fBMS_SHARED\fP؛ وبالمثل، إذا كان \fIput_old\fP نقطة وصل موجودة، يجب ألا يكون نوع انتشارها \fBMS_SHARED\fP. تضمن هذه القيود أن \fBpivot_root\fP() لا ينشر أي تغييرات أبدًا إلى مساحة أسماء وصل أخرى. .IP \[bu] يجب أن يكون الدليل الجذري الحالي نقطة وصل. .SH "قيمة الإرجاع" عند النجاح، يُعاد الصفر. وعند حدوث خطأ، يُعاد الرقم \-1، ويُضبط \fIerrno\fP للإشارة إلى الخطأ. .SH الأخطاء قد يفشل \fBpivot_root\fP() مع أي من نفس الأخطاء مثل \fBstat\fP(2). بالإضافة إلى ذلك، قد يفشل مع الأخطاء التالية: .TP \fBEBUSY\fP .\" Reconfirmed that the following error occurs on Linux 5.0 by .\" specifying 'new_root' as "/rootfs" and 'put_old' as .\" "/rootfs/oldrootfs", and *not* bind mounting "/rootfs" on top of .\" itself. Of course, this is an odd situation, since a later check .\" in the kernel code will in any case yield EINVAL if 'new_root' is .\" not a mount point. However, when the system call was first added, .\" 'new_root' was not required to be a mount point. So, this .\" error is nowadays probably just the result of crufty accumulation. .\" This error can also occur if we bind mount "/" on top of itself .\" and try to specify "/" as the 'new' (again, an odd situation). So, .\" the EBUSY check in the kernel does still seem necessary to prevent .\" that case. Furthermore, the "or put_old" piece is probably .\" redundant text (although the check is in the kernel), since, .\" in another check, 'put_old' is required to be under 'new_root'. \fInew_root\fP أو \fIput_old\fP على نقطة الوصل الجذرية الحالية. (يغطي هذا الخطأ الحالة المرضية حيث \fInew_root\fP هو \fI\[dq]/\[dq]\fP.) .TP \fBEINVAL\fP \fInew_root\fP ليس نقطة وصل. .TP \fBEINVAL\fP \fIput_old\fP ليس عند أو أسفل \fInew_root\fP. .TP \fBEINVAL\fP الدليل الجذري الحالي ليس نقطة وصل (بسبب \fBchroot\fP(2) سابق). .TP \fBEINVAL\fP الجذر الحالي على نقطة وصل rootfs (ramfs الأولية)؛ انظر الملاحظات. .TP \fBEINVAL\fP إما نقطة الوصل عند \fInew_root\fP، أو نقطة الوصل الأم لتلك النقطة، لها نوع انتشار \fBMS_SHARED\fP. .TP \fBEINVAL\fP \fIput_old\fP هو نقطة وصل وله نوع انتشار \fBMS_SHARED\fP. .TP \fBENOTDIR\fP \fInew_root\fP أو \fIput_old\fP ليس دليلاً. .TP \fBEPERM\fP لا تمتلك العملية المستدعية إمكانية \fBCAP_SYS_ADMIN\fP. .SH المعايير لينكس. .SH التاريخ لينكس 2.3.41. .SH ملاحظات توفر \fBpivot_root\fP(8) واجهة سطر أوامر لاستدعاء النظام هذا. .P يسمح \fBpivot_root\fP() للمستدعي بالتبديل إلى نظام ملفات جذري جديد مع وضع نقطة الوصل الجذرية القديمة في موقع تحت \fInew_root\fP حيث يمكن فصلها لاحقًا. (حقيقة أنه ينقل جميع العمليات التي لديها دليل جذري أو دليل عمل حالي على الدليل الجذري القديم إلى الجذر الجديد يحرر الدليل الجذري القديم من المستخدمين، مما يسمح بفصل نقطة الوصل الجذرية القديمة بسهولة أكبر.) .P أحد استخدامات \fBpivot_root\fP() هو أثناء بدء تشغيل النظام، عندما يقوم النظام بوصل نظام ملفات جذري مؤقت (مثل \fBinitrd\fP(4))، ثم يصل نظام الملفات الجذري الحقيقي، ويحول الأخير في النهاية إلى الدليل الجذري لجميع العمليات والخيوط ذات الصلة. استخدام حديث هو إعداد نظام ملفات جذري أثناء إنشاء حاوية. .P حقيقة أن \fBpivot_root\fP() يعدل الدلائل الجذرية ودلائل العمل الحالية للعمليات بالطريقة المذكورة في الوصف ضرورية لمنع خيوط النواة من إبقاء نقطة الوصل الجذرية القديمة مشغولة بدلائلها الجذرية ودلائل العمل الحالية، حتى لو لم تصل إلى نظام الملفات بأي شكل. .P .\" لا يمكن تطبيق \fBpivot_root\fP() على rootfs (ramfs الأولية). الطريقة الموصى بها لتغيير نظام الملفات الجذري في هذه الحالة هي حذف كل شيء في rootfs، ووصل rootfs فوقه بالجذر الجديد، وإرفاق \fIstdin\fP/\fIstdout\fP/\fIstderr\fP بـ \fI/dev/console\fP الجديد، وتنفيذ \fBinit\fP(1) الجديد. توجد برامج مساعدة لهذه العملية؛ انظر \fBswitch_root\fP(8). .SS "pivot_root(\[dq].\[dq], \[dq].\[dq])" يمكن أن يكون \fInew_root\fP و \fIput_old\fP نفس الدليل. على وجه الخصوص، يسمح التسلسل التالي بعملية pivot\-root دون الحاجة إلى إنشاء وإزالة دليل مؤقت: .P .in +4n .EX chdir(new_root); pivot_root(".", "."); umount2(".", MNT_DETACH); .EE .in .P .\" ينجح هذا التسلسل لأن استدعاء \fBpivot_root\fP() يكدس نقطة وصل الجذر القديم فوق نقطة وصل الجذر الجديد في \fI/\fP. في تلك النقطة، يشير دليل الجذر ودليل العمل الحالي لعملية الاستدعاء إلى نقطة وصل الجذر الجديد (\fInew_root\fP). أثناء استدعاء \fBumount\fP() اللاحق، يبدأ تحليل \fI\[dq].\[dq]\fP من \fInew_root\fP ثم يتحرك لأعلى قائمة الوصلات المكدسة في \fI/\fP، مما يؤدي إلى فك وصل نقطة وصل الجذر القديم. .SS "ملاحظات تاريخية" لسنوات عديدة، حملت صفحة الدليل هذه النص التالي: .RS .P قد يغير \fBpivot_root\fP() أو لا يغير الجذر الحالي ودليل العمل الحالي لأي عمليات أو خيوط تستخدم دليل الجذر القديم. يجب على مستدعي \fBpivot_root\fP() التأكد من أن العمليات التي لها جذر أو دليل عمل حالي في الجذر القديم تعمل بشكل صحيح في كلتا الحالتين. طريقة سهلة لضمان ذلك هي تغيير جذرها ودليل عملها الحالي إلى \fInew_root\fP قبل استدعاء \fBpivot_root\fP(). .RE .P هذا النص، الذي كتب قبل حتى الانتهاء من تنفيذ استدعاء النظام في النواة، ربما كان يهدف إلى تحذير المستخدمين في ذلك الوقت بأن التنفيذ قد يتغير قبل الإصدار النهائي. ومع ذلك، ظل السلوك المذكور في الوصف ثابتًا منذ تنفيذ استدعاء النظام هذا لأول مرة ولن يتغير الآن. .SH أمثلة .\" FIXME .\" Would it be better, because simpler, to use unshare(2) .\" rather than clone(2) in the example below? يوضح البرنامج أدناه استخدام \fBpivot_root\fP() داخل مساحة اسم وصل تم إنشاؤها باستخدام \fBclone\fP(2). بعد التمحور إلى دليل الجذر المسمى في وسيطة سطر الأوامر الأولى للبرنامج، ينفذ الطفل الذي أنشأه \fBclone\fP(2) البرنامج المسمى في وسيطات سطر الأوامر المتبقية. .P نوضح البرنامج عن طريق إنشاء دليل سيعمل كنظام ملفات جذر جديد ووضع نسخة من الملف التنفيذي \fBbusybox\fP(1) (المرتبط بشكل ثابت) في ذلك الدليل. .P .in +4n .EX $\fB mkdir /tmp/rootfs\fP; $\fB ls \-id /tmp/rootfs\fP; # Show inode number of new root directory 319459 /tmp/rootfs $\fB cp $(which busybox) /tmp/rootfs\fP; $\fB PS1=\[aq]bbsh$ \[aq] sudo ./pivot_root_demo /tmp/rootfs /busybox sh\fP; bbsh$\fB PATH=/\fP; bbsh$\fB busybox ln busybox ln\fP; bbsh$\fB ln busybox echo\fP; bbsh$\fB ln busybox ls\fP; bbsh$\fB ls\fP; busybox echo ln ls bbsh$\fB ls \-id /\fP; # Compare with inode number above 319459 / bbsh$\fB echo \[aq]hello world\[aq]\fP; hello world .EE .in .SS "مصدر البرنامج" \& .P .\" SRC BEGIN (pivot_root.c) .EX /* pivot_root_demo.c */ \& #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include \& static int pivot_root(const char *new_root, const char *put_old) { return syscall(SYS_pivot_root, new_root, put_old); } \& #define STACK_SIZE (1024 * 1024) \& static int /* Startup function for cloned child */ child(void *arg) { char path[PATH_MAX]; char **args = arg; char *new_root = args[0]; const char *put_old = "/oldrootfs"; \& /* Ensure that \[aq]new_root\[aq] and its parent mount don\[aq]t have shared propagation (which would cause pivot_root() to return an error), and prevent propagation of mount events to the initial mount namespace. */ \& if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL) == \-1) err(EXIT_FAILURE, "mount\-MS_PRIVATE"); \& /* Ensure that \[aq]new_root\[aq] is a mount point. */ \& if (mount(new_root, new_root, NULL, MS_BIND, NULL) == \-1) err(EXIT_FAILURE, "mount\-MS_BIND"); \& /* Create directory to which old root will be pivoted. */ \& snprintf(path, sizeof(path), "%s/%s", new_root, put_old); if (mkdir(path, 0777) == \-1) err(EXIT_FAILURE, "mkdir"); \& /* And pivot the root filesystem. */ \& if (pivot_root(new_root, path) == \-1) err(EXIT_FAILURE, "pivot_root"); \& /* Switch the current working directory to "/". */ \& if (chdir("/") == \-1) err(EXIT_FAILURE, "chdir"); \& /* Unmount old root and remove mount point. */ \& if (umount2(put_old, MNT_DETACH) == \-1) perror("umount2"); if (rmdir(put_old) == \-1) perror("rmdir"); \& /* Execute the command specified in argv[1]... */ \& execv(args[1], &args[1]); err(EXIT_FAILURE, "execv"); } \& int main(int argc, char *argv[]) { char *stack; \& /* Create a child process in a new mount namespace. */ \& stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, \-1, 0); if (stack == MAP_FAILED) err(EXIT_FAILURE, "mmap"); \& if (clone(child, stack + STACK_SIZE, CLONE_NEWNS | SIGCHLD, &argv[1]) == \-1) err(EXIT_FAILURE, "clone"); \& /* Parent falls through to here; wait for child. */ \& if (wait(NULL) == \-1) err(EXIT_FAILURE, "wait"); \& exit(EXIT_SUCCESS); } .EE .\" SRC END .SH "انظر أيضًا" \fBchdir\fP(2), \fBchroot\fP(2), \fBmount\fP(2), \fBstat\fP(2), \fBinitrd\fP(4), \fBmount_namespaces\fP(7), \fBpivot_root\fP(8), \fBswitch_root\fP(8) .PP .SH ترجمة تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي . .PP هذه الترجمة هي وثيقة مجانية؛ راجع .UR https://www.gnu.org/licenses/gpl-3.0.html رخصة جنو العامة الإصدار 3 .UE أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات. .PP إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: .MT kde-l10n-ar@kde.org .ME .