From baaa1bd58a5c2aca87e60c640199bef1ea2aa492 Mon Sep 17 00:00:00 2001 From: Super User Date: Wed, 24 May 2023 16:02:44 +0800 Subject: [PATCH] add patch.tar.gz --- patch.tar.gz | Bin 0 -> 353207 bytes ...-pause-move-pause-function-to-docker.patch | 616 -- ...2-pause-docker-pause-set-timeout-30s.patch | 76 - ...-integration-testing-faile-about-doc.patch | 50 - ...prjquota-support-set-filesystem-quot.patch | 398 - ...uota-fix-few-overlay2-quota-problems.patch | 37 - ...overlay2-quota-control-backward-comp.patch | 53 - patch/0007-filelimit-Add-file-fds-limit.patch | 319 - ...-Ignore-host-kernel-whether-suport-f.patch | 104 - ...eck-add-healthycheck-in-_ping-add-se.patch | 128 - ...otation-add-annotation-into-cli-flag.patch | 149 - ...1-hookspec-Allow-adding-custom-hooks.patch | 288 - ...kspec-Security-enhancement-for-hooks.patch | 82 - ...ec-Add-bash-completion-for-hook-spec.patch | 31 - ...Add-default-hooks-for-all-containers.patch | 367 - ...hookspec-add-limit-of-hook-spec-file.patch | 72 - ...ec-fix-hooks-nil-pointer-dereference.patch | 31 - ...canonicalize-hook-path-before-valida.patch | 45 - ...ck-add-trylock-and-trylocktimeout-fo.patch | 362 - ...-container-name-and-id-when-create-d.patch | 31 - ...emove-redundant-files-in-graphdriver.patch | 441 - patch/0021-umask-support-specify-umask.patch | 125 - ...-nil-pointer-on-c.Annotations-in-set.patch | 42 - ...ota-fix-syscall-bugs-in-projectquota.patch | 65 - ...-spec-Compatibility-modifications-fo.patch | 51 - ...limit-enable-unlimited-usage-of-memo.patch | 44 - ...a-use-dockerd-quota-size-when-docker.patch | 37 - ...dd-files_panic_enable-to-masked-path.patch | 30 - ...denable-fdstat-and-fdthreshold-to-ma.patch | 34 - ...i-add-oom_extend-to-proc-masked-path.patch | 43 - ...ix-docker-stats-blocked-while-docker.patch | 34 - ...ncase-deadlock-when-kill-the-docker-.patch | 66 - ...-Add-udev-event-time-out-to-fix-dock.patch | 254 - ...-Fix-devicemapper-issue-power-off-th.patch | 224 - ...eject-to-restart-container-when-remo.patch | 42 - ...o-not-reset-container-restartCount-o.patch | 41 - ...d-liver-restore-to-OPTIION-to-enable.patch | 50 - ...-devicemapper-ignore-error-when-remo.patch | 44 - ...emove-redundant-Mounts-when-start-do.patch | 361 - ...r-devicemapper-add-API-GetDeviceList.patch | 166 - ...-devmapper-remove-broken-device-when.patch | 69 - ...ci-Cannot-join-own-pid-ipc-namespace.patch | 137 - ...ke-sure-the-pid-exist-in-pidfile-is-.patch | 81 - ...x-plugin-security-bug-caused-by-unch.patch | 99 - ...afely-remove-overlay-layer-directory.patch | 122 - ...-more-error-info-when-dial-docker.so.patch | 57 - ...-fix-panic-slice-bounds-out-of-range.patch | 59 - ...ocker-check-metadata-when-load-layer.patch | 36 - ...leanup-useless-netns-file-in-var-run.patch | 81 - ...ke-v.opts-to-nil-if-opts.json-is-nul.patch | 39 - ...ix-panic-when-load-maliciously-image.patch | 102 - ...ck-the-RWLayer-while-committing-expo.patch | 194 - ...move-init-layer-when-no-space-to-cre.patch | 46 - ...move-init-layer-if-fails-in-initMoun.patch | 78 - ...nge-checking-for-memory-and-memory.s.patch | 84 - ...cker-check-cpuset.cpu-and-cpuset.mem.patch | 132 - ...-Ignore-ToDisk-error-in-StateChanged.patch | 55 - ...leanup-incompleted-device-while-dock.patch | 35 - ...avoid-middle-state-while-removing-im.patch | 110 - ...-check-when-execute-docker-cp-export.patch | 90 - ...eck-seccomp-file-size-max-10M-before.patch | 54 - ...eck-file-size-before-reading-envfile.patch | 87 - ...test-fix-umask-make-file-mode-failed.patch | 38 - ...066-test-skip-swarm-integration-test.patch | 2090 ----- ...pause-fix-build-missing-dep-packages.patch | 5759 ------------ ...-docker-stop-stuck-on-paused-contain.patch | 54 - ...se-fix-log-pause-unpause-event-twice.patch | 108 - ...t-fix-umask-make-syscall-test-failed.patch | 39 - ...r-Increace-udev-wait-timeout-to-185s.patch | 44 - ...-test-can-not-stop-paused-container-.patch | 36 - ...pdate-docker.service-with-old-revisi.patch | 68 - patch/0076-version-add-EulerVersion.patch | 199 - ...x-file-not-exist-for-check-file-size.patch | 32 - ...8-spec-add-missing-sysconfigs-to-rpm.patch | 53 - ...ix-deadlock-for-docker-commit-export.patch | 39 - ...elinux-Add-selinux-policy-for-docker.patch | 1439 --- ...pec-revert-the-modify-of-runtime-spe.patch | 51 - ...0083-test-fix-start-paused-container.patch | 32 - .../0084-test-skip-pause-test-with-ctr.patch | 47 - ...t-log-detailed-event-with-info-level.patch | 129 - ...ix-daemon-restart-with-restart-alway.patch | 62 - ...add-timeout-return-for-getExitStatus.patch | 48 - ...nerd-fix-stuck-when-containerd-in-T-.patch | 31 - ...0-overlay2-Use-index-off-if-possible.patch | 73 - ...-overlay2-use-global-logger-instance.patch | 168 - ...cker-Lock-the-RWLayer-while-committi.patch | 214 - ...-not-try-to-connect-containerd-if-co.patch | 31 - ...ange-health-check-minum-param-to-one.patch | 88 - ...able-container-health-check-after-re.patch | 41 - ...use-check-tasks-before-updateCgroups.patch | 52 - ...ix-restart-unless-stopped-not-stop-f.patch | 45 - ...on-cli-fix-TestInspectAPIImageRespon.patch | 30 - patch/0100-proquota-fix-quota-basesize.patch | 63 - ...dd-judge-for-client-in-case-of-panic.patch | 34 - ....09-fix-docker-stop-error-if-docker-.patch | 57 - patch/0103-docker-fix-parsing-name-with.patch | 62 - ...ats-increase-the-timeout-of-docker-s.patch | 29 - ...-pause-fix-pause-on-exited-container.patch | 55 - ...engine-selinux-support-selinux-enabl.patch | 2759 ------ ...leanup-container-meta-data-when-task.patch | 37 - ...x-can-t-run-image-while-the-image-is.patch | 107 - ...9-graphdriver-add-Checkparent-method.patch | 199 - ...x-can-t-pull-image-while-the-image-i.patch | 139 - ...docker-overlay2-quota-control-bugfix.patch | 46 - ...0114-docker-mask-internal-proc-files.patch | 46 - patch/0115-docker-enable-bep-ldflags.patch | 54 - .../0116-docker-build-with-relro-flags.patch | 40 - ...ck-synchronize-the-healthcheck-statu.patch | 34 - ...118-docker-fix-opened-file-not-close.patch | 39 - patch/0119-docker-set-makefile-buildid.patch | 41 - ...x-docker-logs-hangs-when-using-journ.patch | 30 - ...cker-add-start-timeout-for-container.patch | 73 - ...ocal-db-on-first-start-after-os-star.patch | 87 - ...123-docker-support-exit-on-unhealthy.patch | 90 - ...-Support-compress-when-saving-images.patch | 368 - ...r-add-hugetlb-limit-option-to-docker.patch | 642 -- ...pass-root-to-chroot-to-for-chroot-ta.patch | 551 -- ...cker-support-docker-cli-using-syslog.patch | 227 - ...d-log-forwarding-mechanism-and-print.patch | 103 - patch/0128-docker-fix-CVE-2019-13509.patch | 84 - ...dd-validation-for-ref-CVE-2019-13139.patch | 92 - ...eck-if-image-exists-in-memory-when-p.patch | 142 - ...Handle-blocked-I-O-of-exec-d-process.patch | 148 - ...ker-mask-internal-proc-add-livepatch.patch | 28 - ...1-docker-fix-mount-loop-on-docker-cp.patch | 138 - ...p-when-container-source-path-is-root.patch | 41 - ...x-docker-pull-406-error-on-some-regi.patch | 34 - ...xed-docker-ps-and-docker-inspect-sta.patch | 90 - ...er-delete-containerd-db-first-reboot.patch | 60 - ...e-to-check-healthy-instead-of-return.patch | 26 - ...-fix-reboot-dirty-data-in-containerd.patch | 109 - ...er-add-loaded-time-to-images-inspect.patch | 149 - ...-docker-printf-execid-when-task-exit.patch | 31 - ...er-add-timestamp-when-setup-iptables.patch | 33 - ...x-updateUnpauseStats-wrong-path-erro.patch | 34 - patch/0141-docker-remove-logo-info.patch | 43 - patch/0142-docker-add-copyright.patch | 79 - patch/0142-docker-fix-fd-leak-on-reboot.patch | 164 - ...t-on-unhealthy-flag-for-health-check.patch | 40 - patch/0143-docker-add-license.patch | 71 - ...x-testcase-TestAttachClosedOnContain.patch | 31 - ...4-docker-hide-some-path-in-container.patch | 62 - ...-hot-upgrade-support-default-runtime.patch | 55 - ...er-hot-upgrade-support-accel-plugins.patch | 123 - ...t-upgrade-treat-empty-storage-opt-as.patch | 33 - ...ocker-ignore-warning-for-docker-info.patch | 34 - ...eck-running-containers-before-del-db.patch | 33 - ...ocker-fix-set-read-deadline-not-work.patch | 75 - ...tting-env-variable-to-disable-db-del.patch | 31 - ...ble-disable-legacy-registry-function.patch | 53 - patch/0153-docker-clean-code.patch | 204 - ...-docker-fix-merge-accel-env-rewriten.patch | 71 - ...ate-log-opt-when-upgrade-from-1.11.2.patch | 32 - ...te-log-opt-tag-for-containers-from-1.patch | 65 - ...heck-manifest-and-layer-s-DiffID-inf.patch | 52 - ...0158-docker-support-private-registry.patch | 904 -- ...cker-extend-timeout-in-cli-testcases.patch | 72 - ...soft-link-from-runtime-default-to-ru.patch | 89 - ...e-containerd-object-on-start-failure.patch | 54 - ...62-docker-remove-redundant-word-item.patch | 25 - ...-delete-event-is-not-need-to-process.patch | 27 - ...ess-exit-file-when-kill-process-dire.patch | 36 - ...er-use-git-commit-to-store-commit-ID.patch | 39 - patch/0165-docker-sync-cli-vendor.patch | 38 - patch/0167-docker-fix-CVE-2020-13401.patch | 69 - ...-messages-for-ops-when-device-not-fo.patch | 27 - .../0168-docker-do-not-add-w-to-LDFLAGS.patch | 79 - ...69-docker-add-files-in-proc-for-mask.patch | 42 - ...70-docker-fix-docker-load-files-leak.patch | 27 - ...-do-not-sync-if-BYPAAS_SYNC-is-false.patch | 28 - ...ix-panic-on-single-character-volumes.patch | 27 - ...fix-stats-memory-usage-display-error.patch | 38 - ...-docker-clean-docker-load-leak-files.patch | 85 - ...nts-engine-vendor-add-riscv64-config.patch | 77 - patch/0175-docker-mask-proc-pin_memory.patch | 25 - ...vendor-add-new-config-file-for-riscv.patch | 8079 ----------------- ...ainer-process-if-its-status-is-not-r.patch | 62 - ...vendor-add-new-config-file-for-riscv.patch | 7730 ---------------- patch/0177-resume-suspend-dm-on-start.patch | 82 - ...-and-restart-containerd-during-docke.patch | 85 - patch/0179-handle-exit-force.patch | 107 - ...-wait-io-with-timeout-in-task-delete.patch | 47 - ...-return-when-matched-registry-mirror.patch | 137 - ...-pagealloc_module-and-slaballoc_stat.patch | 29 - ...ith-timeout-when-process-Start-faile.patch | 48 - ...age-reference-when-failed-to-get-ima.patch | 63 - ...ix-execCommands-leak-in-health-check.patch | 67 - ...-check-containerd-pid-before-kill-it.patch | 121 - ...s-to-remapped-root-allows-privilege-.patch | 446 - patch/0190-docker-fix-CVE-2021-21285.patch | 54 - ...docker-restart-when-doing-BlkDiscard.patch | 55 - patch/0192-fix-dangling-unpigz.patch | 25 - 192 files changed, 46067 deletions(-) create mode 100644 patch.tar.gz delete mode 100644 patch/0001-pause-move-pause-function-to-docker.patch delete mode 100644 patch/0002-pause-docker-pause-set-timeout-30s.patch delete mode 100644 patch/0003-pause-fix-integration-testing-faile-about-doc.patch delete mode 100644 patch/0004-prjquota-support-set-filesystem-quot.patch delete mode 100644 patch/0005-prjquota-fix-few-overlay2-quota-problems.patch delete mode 100644 patch/0006-prjquota-overlay2-quota-control-backward-comp.patch delete mode 100644 patch/0007-filelimit-Add-file-fds-limit.patch delete mode 100644 patch/0008-filelimit-Ignore-host-kernel-whether-suport-f.patch delete mode 100644 patch/0009-healthycheck-add-healthycheck-in-_ping-add-se.patch delete mode 100644 patch/0010-annotation-add-annotation-into-cli-flag.patch delete mode 100644 patch/0011-hookspec-Allow-adding-custom-hooks.patch delete mode 100644 patch/0012-hookspec-Security-enhancement-for-hooks.patch delete mode 100644 patch/0013-hookspec-Add-bash-completion-for-hook-spec.patch delete mode 100644 patch/0014-hookspec-Add-default-hooks-for-all-containers.patch delete mode 100644 patch/0015-hookspec-add-limit-of-hook-spec-file.patch delete mode 100644 patch/0016-hookspec-fix-hooks-nil-pointer-dereference.patch delete mode 100644 patch/0017-hookspec-canonicalize-hook-path-before-valida.patch delete mode 100644 patch/0018-dfx-trylock-add-trylock-and-trylocktimeout-fo.patch delete mode 100644 patch/0019-dfx-print-container-name-and-id-when-create-d.patch delete mode 100644 patch/0020-cleanup-remove-redundant-files-in-graphdriver.patch delete mode 100644 patch/0021-umask-support-specify-umask.patch delete mode 100644 patch/0022-umask-fix-nil-pointer-on-c.Annotations-in-set.patch delete mode 100644 patch/0023-prjquota-fix-syscall-bugs-in-projectquota.patch delete mode 100644 patch/0024-runtime-spec-Compatibility-modifications-fo.patch delete mode 100644 patch/0025-resource-limit-enable-unlimited-usage-of-memo.patch delete mode 100644 patch/0026-prjquota-use-dockerd-quota-size-when-docker.patch delete mode 100644 patch/0027-oci-add-files_panic_enable-to-masked-path.patch delete mode 100644 patch/0028-oci-add-fdenable-fdstat-and-fdthreshold-to-ma.patch delete mode 100644 patch/0029-oci-add-oom_extend-to-proc-masked-path.patch delete mode 100644 patch/0030-restart-fix-docker-stats-blocked-while-docker.patch delete mode 100644 patch/0031-restart-Incase-deadlock-when-kill-the-docker-.patch delete mode 100644 patch/0032-devmapper-Add-udev-event-time-out-to-fix-dock.patch delete mode 100644 patch/0033-devmapper-Fix-devicemapper-issue-power-off-th.patch delete mode 100644 patch/0035-restart-reject-to-restart-container-when-remo.patch delete mode 100644 patch/0036-restart-do-not-reset-container-restartCount-o.patch delete mode 100644 patch/0037-config-Add-liver-restore-to-OPTIION-to-enable.patch delete mode 100644 patch/0038-devmapper-devicemapper-ignore-error-when-remo.patch delete mode 100644 patch/0039-restart-Remove-redundant-Mounts-when-start-do.patch delete mode 100644 patch/0040-devmapper-devicemapper-add-API-GetDeviceList.patch delete mode 100644 patch/0041-devmapper-devmapper-remove-broken-device-when.patch delete mode 100644 patch/0042-oci-Cannot-join-own-pid-ipc-namespace.patch delete mode 100644 patch/0043-docker-Make-sure-the-pid-exist-in-pidfile-is-.patch delete mode 100644 patch/0044-plugin-Fix-plugin-security-bug-caused-by-unch.patch delete mode 100644 patch/0045-overlay-safely-remove-overlay-layer-directory.patch delete mode 100644 patch/0046-debug-add-more-error-info-when-dial-docker.so.patch delete mode 100644 patch/0047-docker-fix-panic-slice-bounds-out-of-range.patch delete mode 100644 patch/0048-docker-check-metadata-when-load-layer.patch delete mode 100644 patch/0049-cleanup-cleanup-useless-netns-file-in-var-run.patch delete mode 100644 patch/0050-volume-Make-v.opts-to-nil-if-opts.json-is-nul.patch delete mode 100644 patch/0051-docker-fix-panic-when-load-maliciously-image.patch delete mode 100644 patch/0052-docker-Lock-the-RWLayer-while-committing-expo.patch delete mode 100644 patch/0053-docker-remove-init-layer-when-no-space-to-cre.patch delete mode 100644 patch/0054-docker-remove-init-layer-if-fails-in-initMoun.patch delete mode 100644 patch/0055-docker-range-checking-for-memory-and-memory.s.patch delete mode 100644 patch/0056-docker-check-cpuset.cpu-and-cpuset.mem.patch delete mode 100644 patch/0057-docker-Ignore-ToDisk-error-in-StateChanged.patch delete mode 100644 patch/0058-cleanup-cleanup-incompleted-device-while-dock.patch delete mode 100644 patch/0059-overlay2-avoid-middle-state-while-removing-im.patch delete mode 100644 patch/0060-debug-Add-check-when-execute-docker-cp-export.patch delete mode 100644 patch/0061-docker-check-seccomp-file-size-max-10M-before.patch delete mode 100644 patch/0062-docker-check-file-size-before-reading-envfile.patch delete mode 100644 patch/0063-test-fix-umask-make-file-mode-failed.patch delete mode 100644 patch/0066-test-skip-swarm-integration-test.patch delete mode 100644 patch/0067-pause-fix-build-missing-dep-packages.patch delete mode 100644 patch/0068-pause-fix-docker-stop-stuck-on-paused-contain.patch delete mode 100644 patch/0069-pause-fix-log-pause-unpause-event-twice.patch delete mode 100644 patch/0070-test-fix-umask-make-syscall-test-failed.patch delete mode 100644 patch/0071-devmapper-Increace-udev-wait-timeout-to-185s.patch delete mode 100644 patch/0072-pause-fix-test-can-not-stop-paused-container-.patch delete mode 100644 patch/0073-service-update-docker.service-with-old-revisi.patch delete mode 100644 patch/0076-version-add-EulerVersion.patch delete mode 100644 patch/0077-image-fix-file-not-exist-for-check-file-size.patch delete mode 100644 patch/0078-spec-add-missing-sysconfigs-to-rpm.patch delete mode 100644 patch/0079-rwlayer-fix-deadlock-for-docker-commit-export.patch delete mode 100644 patch/0080-selinux-Add-selinux-policy-for-docker.patch delete mode 100644 patch/0081-runtime-spec-revert-the-modify-of-runtime-spe.patch delete mode 100644 patch/0083-test-fix-start-paused-container.patch delete mode 100644 patch/0084-test-skip-pause-test-with-ctr.patch delete mode 100644 patch/0085-event-log-detailed-event-with-info-level.patch delete mode 100644 patch/0086-restart-fix-daemon-restart-with-restart-alway.patch delete mode 100644 patch/0088-attach-add-timeout-return-for-getExitStatus.patch delete mode 100644 patch/0089-libcontainerd-fix-stuck-when-containerd-in-T-.patch delete mode 100644 patch/0090-overlay2-Use-index-off-if-possible.patch delete mode 100644 patch/0091-overlay2-use-global-logger-instance.patch delete mode 100644 patch/0092-Revert-docker-Lock-the-RWLayer-while-committi.patch delete mode 100644 patch/0093-docker-do-not-try-to-connect-containerd-if-co.patch delete mode 100644 patch/0094-docker-change-health-check-minum-param-to-one.patch delete mode 100644 patch/0095-docker-enable-container-health-check-after-re.patch delete mode 100644 patch/0096-pause-check-tasks-before-updateCgroups.patch delete mode 100644 patch/0097-restart-fix-restart-unless-stopped-not-stop-f.patch delete mode 100644 patch/0099-integration-cli-fix-TestInspectAPIImageRespon.patch delete mode 100644 patch/0100-proquota-fix-quota-basesize.patch delete mode 100644 patch/0101-daeamon-add-judge-for-client-in-case-of-panic.patch delete mode 100644 patch/0102-docker-18.09-fix-docker-stop-error-if-docker-.patch delete mode 100644 patch/0103-docker-fix-parsing-name-with.patch delete mode 100644 patch/0104-docker-stats-increase-the-timeout-of-docker-s.patch delete mode 100644 patch/0105-pause-fix-pause-on-exited-container.patch delete mode 100644 patch/0106-docker-engine-selinux-support-selinux-enabl.patch delete mode 100644 patch/0107-restore-cleanup-container-meta-data-when-task.patch delete mode 100644 patch/0108-docker-Fix-can-t-run-image-while-the-image-is.patch delete mode 100644 patch/0109-graphdriver-add-Checkparent-method.patch delete mode 100644 patch/0110-docker-Fix-can-t-pull-image-while-the-image-i.patch delete mode 100644 patch/0112-docker-overlay2-quota-control-bugfix.patch delete mode 100644 patch/0114-docker-mask-internal-proc-files.patch delete mode 100644 patch/0115-docker-enable-bep-ldflags.patch delete mode 100644 patch/0116-docker-build-with-relro-flags.patch delete mode 100644 patch/0117-healthcheck-synchronize-the-healthcheck-statu.patch delete mode 100644 patch/0118-docker-fix-opened-file-not-close.patch delete mode 100644 patch/0119-docker-set-makefile-buildid.patch delete mode 100644 patch/0120-docker-fix-docker-logs-hangs-when-using-journ.patch delete mode 100644 patch/0121-docker-add-start-timeout-for-container.patch delete mode 100644 patch/0122-cleanup-local-db-on-first-start-after-os-star.patch delete mode 100644 patch/0123-docker-support-exit-on-unhealthy.patch delete mode 100644 patch/0124-docker-Support-compress-when-saving-images.patch delete mode 100644 patch/0125-docker-add-hugetlb-limit-option-to-docker.patch delete mode 100644 patch/0126-docker-pass-root-to-chroot-to-for-chroot-ta.patch delete mode 100644 patch/0127-docker-support-docker-cli-using-syslog.patch delete mode 100644 patch/0128-docker-add-log-forwarding-mechanism-and-print.patch delete mode 100644 patch/0128-docker-fix-CVE-2019-13509.patch delete mode 100644 patch/0129-docker-add-validation-for-ref-CVE-2019-13139.patch delete mode 100644 patch/0129-docker-check-if-image-exists-in-memory-when-p.patch delete mode 100644 patch/0130-docker-Handle-blocked-I-O-of-exec-d-process.patch delete mode 100644 patch/0130-docker-mask-internal-proc-add-livepatch.patch delete mode 100644 patch/0131-docker-fix-mount-loop-on-docker-cp.patch delete mode 100644 patch/0132-docker-fix-docker-cp-when-container-source-path-is-root.patch delete mode 100644 patch/0132-docker-fix-docker-pull-406-error-on-some-regi.patch delete mode 100644 patch/0133-docker-Fixed-docker-ps-and-docker-inspect-sta.patch delete mode 100644 patch/0135-docker-delete-containerd-db-first-reboot.patch delete mode 100644 patch/0136-docker-continue-to-check-healthy-instead-of-return.patch delete mode 100644 patch/0137-docker-fix-reboot-dirty-data-in-containerd.patch delete mode 100644 patch/0138-docker-add-loaded-time-to-images-inspect.patch delete mode 100644 patch/0139-docker-printf-execid-when-task-exit.patch delete mode 100644 patch/0140-docker-add-timestamp-when-setup-iptables.patch delete mode 100644 patch/0141-docker-fix-updateUnpauseStats-wrong-path-erro.patch delete mode 100644 patch/0141-docker-remove-logo-info.patch delete mode 100644 patch/0142-docker-add-copyright.patch delete mode 100644 patch/0142-docker-fix-fd-leak-on-reboot.patch delete mode 100644 patch/0143-docker-add-exit-on-unhealthy-flag-for-health-check.patch delete mode 100644 patch/0143-docker-add-license.patch delete mode 100644 patch/0144-docker-fix-testcase-TestAttachClosedOnContain.patch delete mode 100644 patch/0144-docker-hide-some-path-in-container.patch delete mode 100644 patch/0145-docker-hot-upgrade-support-default-runtime.patch delete mode 100644 patch/0146-docker-hot-upgrade-support-accel-plugins.patch delete mode 100644 patch/0147-docker-hot-upgrade-treat-empty-storage-opt-as.patch delete mode 100644 patch/0148-docker-ignore-warning-for-docker-info.patch delete mode 100644 patch/0149-docker-check-running-containers-before-del-db.patch delete mode 100644 patch/0150-docker-fix-set-read-deadline-not-work.patch delete mode 100644 patch/0151-docker-enable-setting-env-variable-to-disable-db-del.patch delete mode 100644 patch/0152-docker-Enable-disable-legacy-registry-function.patch delete mode 100644 patch/0153-docker-clean-code.patch delete mode 100644 patch/0154-docker-fix-merge-accel-env-rewriten.patch delete mode 100644 patch/0155-docker-update-log-opt-when-upgrade-from-1.11.2.patch delete mode 100644 patch/0156-docker-only-update-log-opt-tag-for-containers-from-1.patch delete mode 100644 patch/0157-docker-Support-check-manifest-and-layer-s-DiffID-inf.patch delete mode 100644 patch/0158-docker-support-private-registry.patch delete mode 100644 patch/0159-docker-extend-timeout-in-cli-testcases.patch delete mode 100644 patch/0160-docker-create-a-soft-link-from-runtime-default-to-ru.patch delete mode 100644 patch/0161-docker-Delete-stale-containerd-object-on-start-failure.patch delete mode 100644 patch/0162-docker-remove-redundant-word-item.patch delete mode 100644 patch/0163-docker-delete-event-is-not-need-to-process.patch delete mode 100644 patch/0164-docker-stat-process-exit-file-when-kill-process-dire.patch delete mode 100644 patch/0164-docker-use-git-commit-to-store-commit-ID.patch delete mode 100644 patch/0165-docker-sync-cli-vendor.patch delete mode 100644 patch/0167-docker-fix-CVE-2020-13401.patch delete mode 100644 patch/0167-dockerd-add-more-messages-for-ops-when-device-not-fo.patch delete mode 100644 patch/0168-docker-do-not-add-w-to-LDFLAGS.patch delete mode 100644 patch/0169-docker-add-files-in-proc-for-mask.patch delete mode 100644 patch/0170-docker-fix-docker-load-files-leak.patch delete mode 100644 patch/0171-docker-do-not-sync-if-BYPAAS_SYNC-is-false.patch delete mode 100644 patch/0172-docker-fix-panic-on-single-character-volumes.patch delete mode 100644 patch/0173-docker-fix-stats-memory-usage-display-error.patch delete mode 100644 patch/0175-docker-clean-docker-load-leak-files.patch delete mode 100644 patch/0175-docker-components-engine-vendor-add-riscv64-config.patch delete mode 100644 patch/0175-docker-mask-proc-pin_memory.patch delete mode 100644 patch/0176-docker-components-engine-vendor-add-new-config-file-for-riscv.patch delete mode 100644 patch/0176-docker-kill-container-process-if-its-status-is-not-r.patch delete mode 100644 patch/0177-docker-components-cli-vendor-add-new-config-file-for-riscv.patch delete mode 100644 patch/0177-resume-suspend-dm-on-start.patch delete mode 100644 patch/0178-docker-skip-kill-and-restart-containerd-during-docke.patch delete mode 100644 patch/0179-handle-exit-force.patch delete mode 100644 patch/0180-wait-io-with-timeout-in-task-delete.patch delete mode 100644 patch/0181-docker-do-not-return-when-matched-registry-mirror.patch delete mode 100644 patch/0183-add-masked-paths-pagealloc_module-and-slaballoc_stat.patch delete mode 100644 patch/0184-docker-wait-io-with-timeout-when-process-Start-faile.patch delete mode 100644 patch/0185-docker-delete-image-reference-when-failed-to-get-ima.patch delete mode 100644 patch/0186-docker-fix-execCommands-leak-in-health-check.patch delete mode 100644 patch/0188-docker-check-containerd-pid-before-kill-it.patch delete mode 100644 patch/0189-docker-fix-Access-to-remapped-root-allows-privilege-.patch delete mode 100644 patch/0190-docker-fix-CVE-2021-21285.patch delete mode 100644 patch/0191-rollback-if-docker-restart-when-doing-BlkDiscard.patch delete mode 100644 patch/0192-fix-dangling-unpigz.patch diff --git a/patch.tar.gz b/patch.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..7c8ba5e01e7e0e4b96cb1931f5d14d7f7466a94c GIT binary patch literal 353207 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

dfXdI~4{ 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

SSq8(5|UNcZPXihwe4tr_f0m$!XY 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'zJBt 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 literal 0 HcmV?d00001 diff --git a/patch/0001-pause-move-pause-function-to-docker.patch b/patch/0001-pause-move-pause-function-to-docker.patch deleted file mode 100644 index 6702df8..0000000 --- a/patch/0001-pause-move-pause-function-to-docker.patch +++ /dev/null @@ -1,616 +0,0 @@ -From 7e41c5cf67a5deaa542d3907a257adf6ae6c976b Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:07:09 +0800 -Subject: [PATCH 001/111] pause: move pause function to docker - -reason: The origin pause function has a long callstack from -docker->containerd->runc,it is waste a lot of time. -Now we move this function to docker, docker will update freeze -cgroup directly. - -Change-Id: I8c26d5b4ed71fb30563db0d4e77167b5b68ccad9 -Signed-off-by: Wentao Zhang -Signed-off-by: zhangyu235 -Signed-off-by: lujingxiao ---- - components/engine/container/container.go | 1 + - components/engine/daemon/daemon.go | 53 ++++++ - components/engine/daemon/freezer/cgroup_fs.go | 94 +++++++++ - .../engine/daemon/freezer/cgroup_systemd.go | 59 ++++++ - components/engine/daemon/freezer/freezer.go | 179 ++++++++++++++++++ - components/engine/daemon/oci_linux.go | 1 + - components/engine/daemon/pause.go | 19 +- - components/engine/daemon/unpause.go | 17 +- - .../engine/libcontainerd/utils_linux.go | 25 +++ - .../engine/libcontainerd/utils_windows.go | 7 +- - 10 files changed, 449 insertions(+), 6 deletions(-) - create mode 100644 components/engine/daemon/freezer/cgroup_fs.go - create mode 100644 components/engine/daemon/freezer/cgroup_systemd.go - create mode 100644 components/engine/daemon/freezer/freezer.go - create mode 100644 components/engine/libcontainerd/utils_linux.go - -diff --git a/components/engine/container/container.go b/components/engine/container/container.go -index 6a5907c34b..f74676f7ee 100644 ---- a/components/engine/container/container.go -+++ b/components/engine/container/container.go -@@ -106,6 +106,7 @@ type Container struct { - // Fields here are specific to Windows - NetworkSharedContainerID string `json:"-"` - SharedEndpointList []string `json:"-"` -+ CgroupParent string - } - - // NewBaseContainer creates a new container with its -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index a307863017..8d6b4d8546 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -35,6 +35,7 @@ import ( - "github.com/docker/docker/daemon/discovery" - "github.com/docker/docker/daemon/events" - "github.com/docker/docker/daemon/exec" -+ "github.com/docker/docker/daemon/freezer" - "github.com/docker/docker/daemon/images" - "github.com/docker/docker/daemon/logger" - "github.com/docker/docker/daemon/network" -@@ -197,6 +198,53 @@ func (daemon *Daemon) NewResolveOptionsFunc() resolver.ResolveOptionsFunc { - } - } - -+func (daemon *Daemon) updatePauseStatus(c *container.Container) error { -+ if !daemon.IsNativeRuntime(c.HostConfig.Runtime) { -+ return nil -+ } -+ -+ // update docker pause status. -+ // for old container, CgroupParent may be empty. -+ if c.CgroupParent == "" { -+ spec, err := libcontainerd.LoadContainerSpec(filepath.Join(daemon.configStore.ExecRoot, "libcontainerd"), c.ID) -+ if err != nil { -+ return err -+ } -+ c.CgroupParent = spec.Linux.CgroupsPath -+ } -+ -+ if !c.IsRunning() { -+ c.Paused = false -+ return nil -+ } -+ -+ useSystemd := UsingSystemd(daemon.configStore) -+ freeze, err := freezer.New(c.ID, c.CgroupParent, useSystemd) -+ if err != nil { -+ return err -+ } -+ -+ paused, err := freeze.IsPaused() -+ if err != nil { -+ return err -+ } -+ c.Paused = paused -+ return nil -+} -+ -+func (daemon *Daemon) IsNativeRuntime(runtime string) bool { -+ // For the containers which created by old docker (do not support multi-runtime) -+ // c.HostConfig.Runtime may be empty. just use the default runtime. -+ if runtime == "" { -+ runtime = daemon.configStore.GetDefaultRuntimeName() -+ } -+ rt := daemon.configStore.GetRuntime(runtime) -+ if rt != nil && filepath.Base(rt.Path) == DefaultRuntimeBinary { -+ return true -+ } -+ return false -+} -+ - func (daemon *Daemon) restore() error { - containers := make(map[string]*container.Container) - -@@ -244,6 +292,11 @@ func (daemon *Daemon) restore() error { - delete(containers, id) - continue - } -+ -+ if err := daemon.updatePauseStatus(c); err != nil { -+ logrus.Errorf("Failed to update pause status for container %s: %s", c.ID, err) -+ } -+ - if err := daemon.Register(c); err != nil { - logrus.Errorf("Failed to register container %s: %s", c.ID, err) - delete(containers, id) -diff --git a/components/engine/daemon/freezer/cgroup_fs.go b/components/engine/daemon/freezer/cgroup_fs.go -new file mode 100644 -index 0000000000..5822c3a659 ---- /dev/null -+++ b/components/engine/daemon/freezer/cgroup_fs.go -@@ -0,0 +1,94 @@ -+package freezer -+ -+import ( -+ "fmt" -+ "os" -+ "path/filepath" -+ "sync" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+ "github.com/opencontainers/runc/libcontainer/utils" -+) -+ -+// The absolute path to the root of the cgroup hierarchies. -+var cgroupRootLock sync.Mutex -+var cgroupRoot string -+ -+func fsCgroupPath(subsystem string, c *configs.Cgroup) (string, error) { -+ rawRoot, err := getCgroupRoot() -+ if err != nil { -+ return "", err -+ } -+ -+ if (c.Name != "" || c.Parent != "") && c.Path != "" { -+ return "", fmt.Errorf("cgroup: either Path or Name and Parent should be used") -+ } -+ -+ // XXX: Do not remove this code. Path safety is important! -- cyphar -+ cgPath := utils.CleanPath(c.Path) -+ cgParent := utils.CleanPath(c.Parent) -+ cgName := utils.CleanPath(c.Name) -+ -+ innerPath := cgPath -+ if innerPath == "" { -+ innerPath = filepath.Join(cgParent, cgName) -+ } -+ -+ mnt, root, err := cgroups.FindCgroupMountpointAndRoot(subsystem) -+ // If we didn't mount the subsystem, there is no point we make the path. -+ if err != nil { -+ return "", err -+ } -+ -+ // If the cgroup name/path is absolute do not look relative to the cgroup of the init process. -+ if filepath.IsAbs(innerPath) { -+ // Sometimes subsystems can be mounted together as 'cpu,cpuacct'. -+ return filepath.Join(rawRoot, filepath.Base(mnt), innerPath), nil -+ } -+ -+ parentPath, err := parentPath(subsystem, mnt, root) -+ if err != nil { -+ return "", err -+ } -+ -+ return filepath.Join(parentPath, innerPath), nil -+} -+ -+func parentPath(subsystem, mountpoint, root string) (string, error) { -+ // Use GetThisCgroupDir instead of GetInitCgroupDir, because the creating -+ // process could in container and shared pid namespace with host, and -+ // /proc/1/cgroup could point to whole other world of cgroups. -+ initPath, err := cgroups.GetOwnCgroup(subsystem) -+ if err != nil { -+ return "", err -+ } -+ // This is needed for nested containers, because in /proc/self/cgroup we -+ // see pathes from host, which don't exist in container. -+ relDir, err := filepath.Rel(root, initPath) -+ if err != nil { -+ return "", err -+ } -+ return filepath.Join(mountpoint, relDir), nil -+} -+ -+func getCgroupRoot() (string, error) { -+ cgroupRootLock.Lock() -+ defer cgroupRootLock.Unlock() -+ -+ if cgroupRoot != "" { -+ return cgroupRoot, nil -+ } -+ -+ root, err := cgroups.FindCgroupMountpointDir() -+ if err != nil { -+ return "", err -+ } -+ -+ if _, err := os.Stat(root); err != nil { -+ return "", err -+ } -+ -+ cgroupRoot = root -+ return cgroupRoot, nil -+} -diff --git a/components/engine/daemon/freezer/cgroup_systemd.go b/components/engine/daemon/freezer/cgroup_systemd.go -new file mode 100644 -index 0000000000..4a05d04910 ---- /dev/null -+++ b/components/engine/daemon/freezer/cgroup_systemd.go -@@ -0,0 +1,59 @@ -+package freezer -+ -+import ( -+ "fmt" -+ "path/filepath" -+ "strings" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/cgroups/systemd" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+var ( -+ systemdEnabledChecked = false -+ systemdEnabled = false -+) -+ -+func SystemdEnabled() bool { -+ if systemdEnabledChecked { -+ return systemdEnabled -+ } -+ systemdEnabledChecked = true -+ systemdEnabled = systemd.UseSystemd() -+ return systemdEnabled -+} -+ -+func systemdCgroupPath(subsystem string, c *configs.Cgroup) (string, error) { -+ mountpoint, err := cgroups.FindCgroupMountpoint(subsystem) -+ if err != nil { -+ return "", err -+ } -+ -+ initPath, err := cgroups.GetInitCgroup(subsystem) -+ if err != nil { -+ return "", err -+ } -+ // if pid 1 is systemd 226 or later, it will be in init.scope, not the root -+ initPath = strings.TrimSuffix(filepath.Clean(initPath), "init.scope") -+ -+ slice := "system.slice" -+ if c.Parent != "" { -+ slice = c.Parent -+ } -+ -+ slice, err = systemd.ExpandSlice(slice) -+ if err != nil { -+ return "", err -+ } -+ -+ return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil -+} -+ -+func getUnitName(c *configs.Cgroup) string { -+ // by default, we create a scope unless the user explicitly asks for a slice. -+ if !strings.HasSuffix(c.Name, ".slice") { -+ return fmt.Sprintf("%s-%s.scope", c.ScopePrefix, c.Name) -+ } -+ return c.Name -+} -diff --git a/components/engine/daemon/freezer/freezer.go b/components/engine/daemon/freezer/freezer.go -new file mode 100644 -index 0000000000..774f5c21ed ---- /dev/null -+++ b/components/engine/daemon/freezer/freezer.go -@@ -0,0 +1,179 @@ -+package freezer -+ -+import ( -+ "bytes" -+ "fmt" -+ "io/ioutil" -+ "os" -+ "path/filepath" -+ "strings" -+ "sync" -+ "time" -+ -+ "github.com/opencontainers/runc/libcontainer/configs" -+ "github.com/opencontainers/runc/libcontainer/utils" -+) -+ -+// Freezer is the interface which could be used to pause/resume container, -+// And it could be used to get the real container paused status of a container too. -+type Freezer interface { -+ // Pause will set the container to pause state by writing freeze cgroup. -+ Pause() error -+ -+ // Resume will set the container to running state by writing freeze cgroup. -+ Resume() error -+ -+ // IsPaused will return if the container is paused or not by reading cgroup information. -+ IsPaused() (bool, error) -+} -+ -+func writeFile(dir, file, data string) error { -+ // Normally dir should not be empty, one case is that cgroup subsystem -+ // is not mounted, we will get empty dir, and we want it fail here. -+ if dir == "" { -+ return fmt.Errorf("no such directory for %s", file) -+ } -+ if err := ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700); err != nil { -+ return fmt.Errorf("failed to write %v to %v: %v", data, file, err) -+ } -+ return nil -+} -+ -+func readFile(dir, file string) (string, error) { -+ data, err := ioutil.ReadFile(filepath.Join(dir, file)) -+ return string(data), err -+} -+ -+// New will create a Freezer interface for caller -+func New(cid, cgroupParent string, useSystemdCgroup bool) (Freezer, error) { -+ if useSystemdCgroup && !SystemdEnabled() { -+ return nil, fmt.Errorf("systemd cgroup flag passed, but systemd support for managing cgroups is not available") -+ } -+ cgroupConfig, err := prepareCgroupConfig(cid, cgroupParent, useSystemdCgroup) -+ if err != nil { -+ return nil, err -+ } -+ -+ return newFreezer(useSystemdCgroup, cgroupConfig) -+} -+ -+func prepareCgroupConfig(cid, cgroupsPath string, useSystemdCgroup bool) (*configs.Cgroup, error) { -+ var myCgroupPath string -+ c := &configs.Cgroup{ -+ Resources: &configs.Resources{}, -+ } -+ if cgroupsPath != "" { -+ myCgroupPath = utils.CleanPath(cgroupsPath) -+ if useSystemdCgroup { -+ myCgroupPath = cgroupsPath -+ } -+ } -+ -+ if useSystemdCgroup { -+ if myCgroupPath == "" { -+ c.Parent = "system.slice" -+ c.ScopePrefix = "runc" -+ c.Name = cid -+ } else { -+ // Parse the path from expected "slice:prefix:name" -+ // for e.g. "system.slice:docker:1234" -+ parts := strings.Split(myCgroupPath, ":") -+ if len(parts) != 3 { -+ return nil, fmt.Errorf("expected cgroupsPath to be of format \"slice:prefix:name\" for systemd cgroups") -+ } -+ c.Parent = parts[0] -+ c.ScopePrefix = parts[1] -+ c.Name = parts[2] -+ } -+ } else { -+ if myCgroupPath == "" { -+ c.Name = cid -+ } -+ c.Path = myCgroupPath -+ } -+ return c, nil -+} -+ -+func newFreezer(useSystemdCgroup bool, cgroup *configs.Cgroup) (Freezer, error) { -+ var err error -+ var path string -+ -+ if useSystemdCgroup { -+ path, err = systemdCgroupPath("freezer", cgroup) -+ if err != nil { -+ return nil, err -+ } -+ } else { -+ path, err = fsCgroupPath("freezer", cgroup) -+ if err != nil { -+ return nil, err -+ } -+ } -+ return &freezer{path: path}, nil -+} -+ -+type freezer struct { -+ sync.Mutex -+ path string -+} -+ -+// Pause will set the container to pause state by writing freeze cgroup. -+func (f *freezer) Pause() error { -+ f.Lock() -+ defer f.Unlock() -+ -+ if err := f.updateCgroup(string(configs.Frozen)); err != nil { -+ return err -+ } -+ -+ tasks, err := readFile(f.path, "tasks") -+ if err != nil { -+ return fmt.Errorf("failed to check container cgroup task status: %v", err) -+ } -+ -+ if strings.TrimSpace(tasks) == "" { -+ return fmt.Errorf("error: no tasks running in freeze cgroup") -+ } -+ return nil -+} -+ -+// Resume will set the container to running state by writing freeze cgroup. -+func (f *freezer) Resume() error { -+ f.Lock() -+ defer f.Unlock() -+ return f.updateCgroup(string(configs.Thawed)) -+} -+ -+// IsPaused will return if the container is paused or not by reading cgroup information. -+func (f *freezer) IsPaused() (bool, error) { -+ f.Lock() -+ defer f.Unlock() -+ -+ data, err := readFile(f.path, "freezer.state") -+ if err != nil { -+ // If freezer cgroup is not mounted, the container would just be not paused. -+ if os.IsNotExist(err) { -+ return false, nil -+ } -+ return false, fmt.Errorf("failed to check container status: %v", err) -+ } -+ return bytes.Equal(bytes.TrimSpace([]byte(data)), []byte("FROZEN")), nil -+} -+ -+func (f *freezer) updateCgroup(state string) error { -+ if err := writeFile(f.path, "freezer.state", state); err != nil { -+ return err -+ } -+ -+ for { -+ newState, err := readFile(f.path, "freezer.state") -+ if err != nil { -+ return err -+ } -+ if strings.TrimSpace(newState) == state { -+ break -+ } -+ time.Sleep(1 * time.Millisecond) -+ } -+ return nil -+} -diff --git a/components/engine/daemon/oci_linux.go b/components/engine/daemon/oci_linux.go -index 7611fc054d..864d22fbcb 100644 ---- a/components/engine/daemon/oci_linux.go -+++ b/components/engine/daemon/oci_linux.go -@@ -711,6 +711,7 @@ func (daemon *Daemon) createSpec(c *container.Container) (retSpec *specs.Spec, e - cgroupsPath = filepath.Join(parent, c.ID) - } - s.Linux.CgroupsPath = cgroupsPath -+ c.CgroupParent = cgroupsPath - - if err := setResources(&s, c.HostConfig.Resources); err != nil { - return nil, fmt.Errorf("linux runtime spec resources: %v", err) -diff --git a/components/engine/daemon/pause.go b/components/engine/daemon/pause.go -index be6ec1b92a..972baa961f 100644 ---- a/components/engine/daemon/pause.go -+++ b/components/engine/daemon/pause.go -@@ -5,6 +5,7 @@ import ( - "fmt" - - "github.com/docker/docker/container" -+ "github.com/docker/docker/daemon/freezer" - "github.com/sirupsen/logrus" - ) - -@@ -38,8 +39,22 @@ func (daemon *Daemon) containerPause(container *container.Container) error { - return errContainerIsRestarting(container.ID) - } - -- if err := daemon.containerd.Pause(context.Background(), container.ID); err != nil { -- return fmt.Errorf("Cannot pause container %s: %s", container.ID, err) -+ if daemon.IsNativeRuntime(container.HostConfig.Runtime) { -+ freezer, err := freezer.New(container.ID, container.CgroupParent, UsingSystemd(daemon.configStore)) -+ if err != nil { -+ return fmt.Errorf("Failed to create freezer for container %s: %v", container.ID, err) -+ } -+ -+ if err := freezer.Pause(); err != nil { -+ return fmt.Errorf("Cannot pause container %s: %v", container.ID, err) -+ } -+ -+ container.Paused = true -+ daemon.LogContainerEvent(container, "pause") -+ } else { -+ if err := daemon.containerd.Pause(context.Background(), container.ID); err != nil { -+ return fmt.Errorf("Cannot pause container %s: %s", container.ID, err) -+ } - } - - container.Paused = true -diff --git a/components/engine/daemon/unpause.go b/components/engine/daemon/unpause.go -index 27648ae72e..4a8225258f 100644 ---- a/components/engine/daemon/unpause.go -+++ b/components/engine/daemon/unpause.go -@@ -5,6 +5,7 @@ import ( - "fmt" - - "github.com/docker/docker/container" -+ "github.com/docker/docker/daemon/freezer" - "github.com/sirupsen/logrus" - ) - -@@ -27,8 +28,20 @@ func (daemon *Daemon) containerUnpause(container *container.Container) error { - return fmt.Errorf("Container %s is not paused", container.ID) - } - -- if err := daemon.containerd.Resume(context.Background(), container.ID); err != nil { -- return fmt.Errorf("Cannot unpause container %s: %s", container.ID, err) -+ if daemon.IsNativeRuntime(container.HostConfig.Runtime) { -+ freezer, err := freezer.New(container.ID, container.CgroupParent, UsingSystemd(daemon.configStore)) -+ if err != nil { -+ return fmt.Errorf("Failed to create freezer for container %s: %v", container.ID, err) -+ } -+ if err := freezer.Resume(); err != nil { -+ return fmt.Errorf("Cannot unpause container %s: %s", container.ID, err) -+ } -+ container.Paused = false -+ daemon.LogContainerEvent(container, "unpause") -+ } else { -+ if err := daemon.containerd.Resume(context.Background(), container.ID); err != nil { -+ return fmt.Errorf("Cannot unpause container %s: %s", container.ID, err) -+ } - } - - container.Paused = false -diff --git a/components/engine/libcontainerd/utils_linux.go b/components/engine/libcontainerd/utils_linux.go -new file mode 100644 -index 0000000000..f9b3e64db9 ---- /dev/null -+++ b/components/engine/libcontainerd/utils_linux.go -@@ -0,0 +1,25 @@ -+package libcontainerd -+ -+import ( -+ "encoding/json" -+ "io/ioutil" -+ "path/filepath" -+ -+ "github.com/opencontainers/runtime-spec/specs-go" -+) -+ -+func LoadContainerSpec(stateDir, id string) (*specs.Spec, error) { -+ var spec specs.Spec -+ dir, err := filepath.Abs(stateDir) -+ if err != nil { -+ return nil, err -+ } -+ dt, err := ioutil.ReadFile(filepath.Join(dir, id, "config.json")) -+ if err != nil { -+ return nil, err -+ } -+ if err := json.Unmarshal(dt, &spec); err != nil { -+ return nil, err -+ } -+ return &spec, nil -+} -diff --git a/components/engine/libcontainerd/utils_windows.go b/components/engine/libcontainerd/utils_windows.go -index aabb9aeaaa..a8ba3629a3 100644 ---- a/components/engine/libcontainerd/utils_windows.go -+++ b/components/engine/libcontainerd/utils_windows.go -@@ -1,6 +1,7 @@ - package libcontainerd // import "github.com/docker/docker/libcontainerd" - - import ( -+ "fmt" - "strings" - - opengcs "github.com/Microsoft/opengcs/client" -@@ -19,10 +20,12 @@ func setupEnvironmentVariables(a []string) map[string]string { - return r - } - -+func LoadContainerSpec(stateDir, id string) (*specs.Spec, error) { -+ return nil, fmt.Errorf("not supported") -+} -+ - // Apply for the LCOW option is a no-op. - func (s *LCOWOption) Apply(interface{}) error { -- return nil --} - - // debugGCS is a dirty hack for debugging for Linux Utility VMs. It simply - // runs a bunch of commands inside the UVM, but seriously aides in advanced debugging. --- -2.17.1 - diff --git a/patch/0002-pause-docker-pause-set-timeout-30s.patch b/patch/0002-pause-docker-pause-set-timeout-30s.patch deleted file mode 100644 index a961427..0000000 --- a/patch/0002-pause-docker-pause-set-timeout-30s.patch +++ /dev/null @@ -1,76 +0,0 @@ -From fb74bc5ce2a510e38b9a8a83d4524876f1881759 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:11:25 +0800 -Subject: [PATCH 002/111] pause: docker pause set timeout 30s - -reason:fix docker pause in infinite loop case,when the process in D status - libcontainer: cgroups: Write freezer state after every state check - This commit ensures we write the expected freezer cgroup state after - every state check, in case the state check does not give the expected - result. This can happen when a new task is created and prevents the - whole cgroup to be FROZEN, leaving the state into FREEZING instead. - This patch prevents the case of an infinite loop to happen. - Cherry-pick from https://github.com/opencontainers/runc/pull/1610 - -Change-Id: Ib5355b9d928c491e120439780c1f03c18aa68b73 -Signed-off-by: panwenxiang -Signed-off-by: zhangyu235 -Signed-off-by: lujingxiao ---- - components/engine/daemon/freezer/freezer.go | 37 +++++++++++++++------ - 1 file changed, 27 insertions(+), 10 deletions(-) - -diff --git a/components/engine/daemon/freezer/freezer.go b/components/engine/daemon/freezer/freezer.go -index 774f5c21ed..cd8b3513d7 100644 ---- a/components/engine/daemon/freezer/freezer.go -+++ b/components/engine/daemon/freezer/freezer.go -@@ -161,19 +161,36 @@ func (f *freezer) IsPaused() (bool, error) { - } - - func (f *freezer) updateCgroup(state string) error { -- if err := writeFile(f.path, "freezer.state", state); err != nil { -- return err -+ curState, err := readFile(f.path, "freezer.state") -+ if err != nil { -+ return fmt.Errorf("read current state failed for %#v", err) - } -+ curState = strings.TrimSpace(curState) - -+ timeout := time.After(30 * time.Second) -+ tick := time.Tick(1 * time.Millisecond) - for { -- newState, err := readFile(f.path, "freezer.state") -- if err != nil { -- return err -- } -- if strings.TrimSpace(newState) == state { -- break -+ select { -+ case <-timeout: -+ if err := writeFile(f.path, "freezer.state", curState); err != nil { -+ return fmt.Errorf("cannot write %s to freezer for %#v", curState, err) -+ } -+ return fmt.Errorf("update freezer cgroup timeout for 30s") -+ case <-tick: -+ // In case this loop does not exit because it doesn't get the expected -+ // state, let's write again this state, hoping it's going to be properly -+ // set this time. Otherwise, this loop could run infinitely, waiting for -+ // a state change that would never happen. -+ if err := writeFile(f.path, "freezer.state", state); err != nil { -+ return fmt.Errorf("cannot write freezer.state for %#v", err) -+ } -+ newState, err := readFile(f.path, "freezer.state") -+ if err != nil { -+ return err -+ } -+ if strings.TrimSpace(newState) == state { -+ return nil -+ } - } -- time.Sleep(1 * time.Millisecond) - } -- return nil - } --- -2.17.1 - diff --git a/patch/0003-pause-fix-integration-testing-faile-about-doc.patch b/patch/0003-pause-fix-integration-testing-faile-about-doc.patch deleted file mode 100644 index a3d8bfb..0000000 --- a/patch/0003-pause-fix-integration-testing-faile-about-doc.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 8a897fcad4bf6d2f4be05bb3075640d65e98ac8e Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:13:24 +0800 -Subject: [PATCH 003/111] pause: fix integration testing faile about - `docker pause` status display - -reason:fix integration testing faile about `docker pause` status display - -Change-Id: I851b29171a33f5eb278800fb0f1e061bebb3745c -Signed-off-by: leizhongkai -Signed-off-by: zhangyu235 -Signed-off-by: lujingxiao ---- - components/engine/daemon/pause.go | 4 ++++ - components/engine/daemon/unpause.go | 4 ++++ - 2 files changed, 8 insertions(+) - -diff --git a/components/engine/daemon/pause.go b/components/engine/daemon/pause.go -index 972baa961f..6f9d8b0f70 100644 ---- a/components/engine/daemon/pause.go -+++ b/components/engine/daemon/pause.go -@@ -50,6 +50,10 @@ func (daemon *Daemon) containerPause(container *container.Container) error { - } - - container.Paused = true -+ daemon.setStateCounter(container) -+ if err := container.CheckpointTo(daemon.containersReplica); err != nil { -+ return err -+ } - daemon.LogContainerEvent(container, "pause") - } else { - if err := daemon.containerd.Pause(context.Background(), container.ID); err != nil { -diff --git a/components/engine/daemon/unpause.go b/components/engine/daemon/unpause.go -index 4a8225258f..290d2b1d0c 100644 ---- a/components/engine/daemon/unpause.go -+++ b/components/engine/daemon/unpause.go -@@ -37,6 +37,10 @@ func (daemon *Daemon) containerUnpause(container *container.Container) error { - return fmt.Errorf("Cannot unpause container %s: %s", container.ID, err) - } - container.Paused = false -+ daemon.setStateCounter(container) -+ if err := container.CheckpointTo(daemon.containersReplica); err != nil { -+ return err -+ } - daemon.LogContainerEvent(container, "unpause") - } else { - if err := daemon.containerd.Resume(context.Background(), container.ID); err != nil { --- -2.17.1 - diff --git a/patch/0004-prjquota-support-set-filesystem-quot.patch b/patch/0004-prjquota-support-set-filesystem-quot.patch deleted file mode 100644 index 5e1fa61..0000000 --- a/patch/0004-prjquota-support-set-filesystem-quot.patch +++ /dev/null @@ -1,398 +0,0 @@ -From a8f05692638bf50826ed9533f2a5282e2cde359d Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:13:41 +0800 -Subject: [PATCH 004/111] prjquota: support set filesystem - quota if ext4 support project quota - -reason:Support set filesystem quota if ext4 support project quota - -Change-Id: I99d28f248e758837cbf8b615e673ee7d8e36be7b -Signed-off-by: Lei Jitang -Signed-off-by: zhangyu235 -Signed-off-by: lujingxiao ---- - components/engine/daemon/daemon_unix.go | 19 ++ - .../daemon/graphdriver/overlay2/overlay.go | 10 +- - .../daemon/graphdriver/quota/projectquota.go | 176 +++++++++++++++--- - .../daemon/graphdriver/vfs/quota_linux.go | 13 +- - 4 files changed, 191 insertions(+), 27 deletions(-) - -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index b69eede21c..1b35df4950 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -633,6 +633,25 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes. - } - } - -+ if hostConfig.StorageOpt != nil && daemon.imageService.GraphDriverForOS(runtime.GOOS) == "overlay2" { -+ _, exist := hostConfig.StorageOpt["size"] -+ if exist { -+ status := daemon.imageService.LayerStoreStatus()[runtime.GOOS] -+ if status[0][0] == "Backing Filesystem" && status[0][1] == "extfs" { -+ if hostConfig.Privileged { -+ warnings = append(warnings, "filesystem quota for overlay2 over ext4 can't take affect with privileged container") -+ } else { -+ for _, cap := range hostConfig.CapAdd { -+ if cap == "SYS_RESOURCE" { -+ warnings = append(warnings, "filesystem quota for overlay2 over ext4 can't take affect with CAP_SYS_RESOURCE") -+ break -+ } -+ } -+ } -+ } -+ } -+ } -+ - return warnings, nil - } - -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index 6b3236f8f3..36ae182bcd 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -216,16 +216,16 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap - - d.naiveDiff = graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps) - -- if backingFs == "xfs" { -- // Try to enable project quota support over xfs. -- if d.quotaCtl, err = quota.NewControl(home); err == nil { -+ if backingFs == "xfs" || backingFs == "extfs" { -+ // Try to enable project quota support over xfs and extfs. -+ if d.quotaCtl, err = quota.NewControl(home, backingFs); err == nil { - projectQuotaSupported = true - } else if opts.quota.Size > 0 { - return nil, fmt.Errorf("Storage option overlay2.size not supported. Filesystem does not support Project Quota: %v", err) - } - } else if opts.quota.Size > 0 { - // if xfs is not the backing fs then error out if the storage-opt overlay2.size is used. -- return nil, fmt.Errorf("Storage Option overlay2.size only supported for backingFS XFS. Found %v", backingFs) -+ return nil, fmt.Errorf("Storage Option overlay2.size only supported for backingFS XFS or ext4. Found %v", backingFs) - } - - logger.Debugf("backingFs=%s, projectQuotaSupported=%v", backingFs, projectQuotaSupported) -@@ -341,7 +341,7 @@ func (d *Driver) Cleanup() error { - // file system. - func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error { - if opts != nil && len(opts.StorageOpt) != 0 && !projectQuotaSupported { -- return fmt.Errorf("--storage-opt is supported only for overlay over xfs with 'pquota' mount option") -+ return fmt.Errorf("--storage-opt is supported only for overlay over xfs or ext4 with 'pquota' mount option") - } - - if opts == nil { -diff --git a/components/engine/daemon/graphdriver/quota/projectquota.go b/components/engine/daemon/graphdriver/quota/projectquota.go -index 93e85823af..7d879eb81d 100644 ---- a/components/engine/daemon/graphdriver/quota/projectquota.go -+++ b/components/engine/daemon/graphdriver/quota/projectquota.go -@@ -38,8 +38,8 @@ struct fsxattr { - #ifndef PRJQUOTA - #define PRJQUOTA 2 - #endif --#ifndef XFS_PROJ_QUOTA --#define XFS_PROJ_QUOTA 2 -+#ifndef PROJ_QUOTA -+#define PROJ_QUOTA 2 - #endif - #ifndef Q_XSETPQLIM - #define Q_XSETPQLIM QCMD(Q_XSETQLIM, PRJQUOTA) -@@ -49,6 +49,28 @@ struct fsxattr { - #endif - - const int Q_XGETQSTAT_PRJQUOTA = QCMD(Q_XGETQSTAT, PRJQUOTA); -+ -+#ifndef Q_XGETPQSTAT -+#define Q_XGETPQSTAT QCMD(Q_XGETQSTAT, PRJQUOTA) -+#endif -+ -+#ifndef Q_SETPQUOTA -+#define Q_SETPQUOTA (unsigned int)QCMD(Q_SETQUOTA, PRJQUOTA) -+#endif -+ -+#ifndef Q_GETPQUOTA -+#define Q_GETPQUOTA (unsigned int)QCMD(Q_GETQUOTA, PRJQUOTA) -+#endif -+ -+#define PDQ_ACCT_BIT 4 -+#define PDQ_ENFD_BIT 5 -+ -+#ifndef QUOTA_PDQ_ACCT -+#define QUOTA_PDQ_ACCT (1<>C.PDQ_ACCT_BIT + (info.qs_flags&C.QUOTA_PDQ_ENFD)>>C.PDQ_ENFD_BIT), nil -+} -+ -+// GetQuota - get the quota limits of a directory that was configured with SetQuota -+func (q *Control) GetQuota(targetPath string, quota *Quota) error { -+ q.lock.Lock() -+ projectID, ok := q.quotas[targetPath] -+ q.lock.Unlock() -+ if !ok { -+ return fmt.Errorf("quota not found for path : %s", targetPath) -+ } -+ -+ // -+ // get the quota limit for the container's project id -+ // -+ -+ return q.quotaOps.GetProjectQuota(q.backingFsBlockDev, projectID, quota) -+} -+ - // getProjectID - get the project id of path on xfs - func getProjectID(targetPath string) (uint32, error) { - dir, err := openDir(targetPath) -diff --git a/components/engine/daemon/graphdriver/vfs/quota_linux.go b/components/engine/daemon/graphdriver/vfs/quota_linux.go -index 0d5c3a7b98..bb2f571834 100644 ---- a/components/engine/daemon/graphdriver/vfs/quota_linux.go -+++ b/components/engine/daemon/graphdriver/vfs/quota_linux.go -@@ -1,6 +1,7 @@ - package vfs // import "github.com/docker/docker/daemon/graphdriver/vfs" - - import ( -+ "github.com/docker/docker/daemon/graphdriver" - "github.com/docker/docker/daemon/graphdriver/quota" - "github.com/sirupsen/logrus" - ) -@@ -10,7 +11,17 @@ type driverQuota struct { - } - - func setupDriverQuota(driver *Driver) { -- if quotaCtl, err := quota.NewControl(driver.home); err == nil { -+ // Probe fs type before setting quota, now only supports xfs and extfs -+ fsMagic, err := graphdriver.GetFSMagic(driver.home) -+ if err != nil { -+ return -+ } -+ fsName, ok := graphdriver.FsNames[fsMagic] -+ if !ok { -+ return -+ } -+ -+ if quotaCtl, err := quota.NewControl(driver.home, fsName); err == nil { - driver.quotaCtl = quotaCtl - } else if err != quota.ErrQuotaNotSupported { - logrus.Warnf("Unable to setup quota: %v\n", err) --- -2.17.1 - diff --git a/patch/0005-prjquota-fix-few-overlay2-quota-problems.patch b/patch/0005-prjquota-fix-few-overlay2-quota-problems.patch deleted file mode 100644 index 605fb81..0000000 --- a/patch/0005-prjquota-fix-few-overlay2-quota-problems.patch +++ /dev/null @@ -1,37 +0,0 @@ -From b5e205b8d1ea0a62ea8847dc5510a10c65a2573e Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:13:57 +0800 -Subject: [PATCH 005/111] prjquota: fix few overlay2 quota problems - -reason:fix few overlay2 quota problems - -Change-Id: Id3a7915747c415d56684c291fb0498d04b762c8c -Signed-off-by: dengguangxing -Signed-off-by: zhangyu235 -Signed-off-by: lujingxiao ---- - components/engine/daemon/graphdriver/overlay2/overlay.go | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index 36ae182bcd..96f44ba9a1 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -455,6 +455,14 @@ func (d *Driver) parseStorageOpt(storageOpt map[string]string, driver *Driver) e - if err != nil { - return err - } -+ // deal with negative and super large number -+ if size < 0 { -+ return fmt.Errorf("Illegal storage size(%s): numerical result out of range", val) -+ } -+ // for overlay (0-1024) means no limit -+ if size < 1024 && size > 0 { -+ return fmt.Errorf("Illegal storage size:%d, 1024 at least", size) -+ } - driver.options.quota.Size = uint64(size) - default: - return fmt.Errorf("Unknown option %s", key) --- -2.17.1 - diff --git a/patch/0006-prjquota-overlay2-quota-control-backward-comp.patch b/patch/0006-prjquota-overlay2-quota-control-backward-comp.patch deleted file mode 100644 index 3fb5ce9..0000000 --- a/patch/0006-prjquota-overlay2-quota-control-backward-comp.patch +++ /dev/null @@ -1,53 +0,0 @@ -From c5a18b46152c4c7016c0c2f0054e276a53f25e1f Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:14:09 +0800 -Subject: [PATCH 006/111] prjquota: overlay2 quota control backward - compability - -reason: In Euleros docker we support default quota control limit -for daemon with commit - docker: Add options to surport default limit for daemon -However in mainstream they have similar commit - 35903110 Add overlay2.size daemon storage-opt -But mainstream uses different api `overlay2.size` compares with -`overlay2.basesize`, so adding this backward compability. - -Change-Id: I36a548bd7f1ce6fab6cad24cfb49faa56f7a1fd1 -Signed-off-by: lujingxiao ---- - components/engine/daemon/graphdriver/overlay2/overlay.go | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index 96f44ba9a1..b969582eb3 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -248,6 +248,7 @@ func parseOptions(options []string) (*overlayOptions, error) { - return nil, err - } - case "overlay2.size": -+ case "overlay2.basesize": - size, err := units.RAMInBytes(val) - if err != nil { - return nil, err -@@ -394,12 +395,16 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr - } - }() - -- if opts != nil && len(opts.StorageOpt) > 0 { -+ if (opts != nil && len(opts.StorageOpt) > 0) || d.options.quota.Size > 0 { - driver := &Driver{} - if err := d.parseStorageOpt(opts.StorageOpt, driver); err != nil { - return err - } - -+ if driver.options.quota.Size == 0 && d.options.quota.Size > 0 { -+ driver.options.quota.Size = d.options.quota.Size -+ } -+ - if driver.options.quota.Size > 0 { - // Set container disk quota limit - if err := d.quotaCtl.SetQuota(dir, driver.options.quota); err != nil { --- -2.17.1 - diff --git a/patch/0007-filelimit-Add-file-fds-limit.patch b/patch/0007-filelimit-Add-file-fds-limit.patch deleted file mode 100644 index ce38212..0000000 --- a/patch/0007-filelimit-Add-file-fds-limit.patch +++ /dev/null @@ -1,319 +0,0 @@ -From 1e26a8c5d18eb93c2786eff9eeede77f3b8162df Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:14:23 +0800 -Subject: [PATCH 007/111] filelimit: Add file fds limit - -Change-Id: I4255fc648ad71dcba78fe38fae9d26454e2e41d8 -Signed-off-by: yangshukui -Signed-off-by: lujingxiao ---- - components/cli/cli/command/container/opts.go | 3 +++ - components/cli/contrib/completion/bash/docker | 1 + - components/cli/contrib/completion/zsh/_docker | 1 + - .../cli/docs/reference/commandline/create.md | 1 + - components/cli/docs/reference/commandline/run.md | 1 + - components/cli/man/docker-run.1.md | 4 ++++ - .../vendor/github.com/docker/docker/api/Checklist | 1 + - .../docker/api/types/container/host_config.go | 1 + - .../engine/api/types/container/host_config.go | 1 + - components/engine/daemon/daemon_unix.go | 6 ++++++ - components/engine/daemon/oci_linux.go | 3 +++ - .../integration-cli/docker_cli_run_unix_test.go | 10 ++++++++++ - .../integration-cli/requirements_unix_test.go | 4 ++++ - components/engine/pkg/sysinfo/sysinfo.go | 6 ++++++ - components/engine/pkg/sysinfo/sysinfo_linux.go | 15 +++++++++++++++ - .../opencontainers/runtime-spec/Checklist | 1 + - .../runtime-spec/specs-go/config.go | 8 ++++++++ - 17 files changed, 67 insertions(+) - create mode 100644 components/cli/vendor/github.com/docker/docker/api/Checklist - create mode 100644 components/engine/vendor/github.com/opencontainers/runtime-spec/Checklist - -diff --git a/components/cli/cli/command/container/opts.go b/components/cli/cli/command/container/opts.go -index 97906b6722..efb28a2cdf 100644 ---- a/components/cli/cli/command/container/opts.go -+++ b/components/cli/cli/command/container/opts.go -@@ -100,6 +100,7 @@ type containerOptions struct { - ipv6Address string - ipcMode string - pidsLimit int64 -+ filesLimit int64 - restartPolicy string - readonlyRootfs bool - loggingDriver string -@@ -271,6 +272,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { - flags.BoolVar(&copts.oomKillDisable, "oom-kill-disable", false, "Disable OOM Killer") - flags.IntVar(&copts.oomScoreAdj, "oom-score-adj", 0, "Tune host's OOM preferences (-1000 to 1000)") - flags.Int64Var(&copts.pidsLimit, "pids-limit", 0, "Tune container pids limit (set -1 for unlimited)") -+ flags.Int64Var(&copts.filesLimit, "files-limit", 0, "Tune container files limit (set -1 for unlimited)") - - // Low-level execution (cgroups, namespaces, ...) - flags.StringVar(&copts.cgroupParent, "cgroup-parent", "", "Optional parent cgroup for the container") -@@ -531,6 +533,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err - CPURealtimePeriod: copts.cpuRealtimePeriod, - CPURealtimeRuntime: copts.cpuRealtimeRuntime, - PidsLimit: copts.pidsLimit, -+ FilesLimit: copts.filesLimit, - BlkioWeight: copts.blkioWeight, - BlkioWeightDevice: copts.blkioWeightDevice.GetList(), - BlkioDeviceReadBps: copts.deviceReadBps.GetList(), -diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker -index 44ac8f3e0e..2e2c8cb04f 100644 ---- a/components/cli/contrib/completion/bash/docker -+++ b/components/cli/contrib/completion/bash/docker -@@ -1789,6 +1789,7 @@ _docker_container_run_and_create() { - --env -e - --env-file - --expose -+ --files-limit - --group-add - --health-cmd - --health-interval -diff --git a/components/cli/contrib/completion/zsh/_docker b/components/cli/contrib/completion/zsh/_docker -index 94f042204d..cbbdfdb798 100644 ---- a/components/cli/contrib/completion/zsh/_docker -+++ b/components/cli/contrib/completion/zsh/_docker -@@ -621,6 +621,7 @@ __docker_container_subcommand() { - "($help)--entrypoint=[Overwrite the default entrypoint of the image]:entry point: " - "($help)*--env-file=[Read environment variables from a file]:environment file:_files" - "($help)*--expose=[Expose a port from the container without publishing it]: " -+ "($help)--files-limit[Tune container files limit (set -1 for max)]" - "($help)*--group=[Set one or more supplementary user groups for the container]:group:_groups" - "($help -h --hostname)"{-h=,--hostname=}"[Container host name]:hostname:_hosts" - "($help -i --interactive)"{-i,--interactive}"[Keep stdin open even if not attached]" -diff --git a/components/cli/docs/reference/commandline/create.md b/components/cli/docs/reference/commandline/create.md -index d585da40ae..5d888183b3 100644 ---- a/components/cli/docs/reference/commandline/create.md -+++ b/components/cli/docs/reference/commandline/create.md -@@ -57,6 +57,7 @@ Options: - -e, --env value Set environment variables (default []) - --env-file value Read in a file of environment variables (default []) - --expose value Expose a port or a range of ports (default []) -+ --files-limit int Tune container files limit (set -1 for unlimited) - --group-add value Add additional groups to join (default []) - --health-cmd string Command to run to check health - --health-interval duration Time between running the check (ns|us|ms|s|m|h) (default 0s) -diff --git a/components/cli/docs/reference/commandline/run.md b/components/cli/docs/reference/commandline/run.md -index 08b9f18d68..21b4fdf261 100644 ---- a/components/cli/docs/reference/commandline/run.md -+++ b/components/cli/docs/reference/commandline/run.md -@@ -61,6 +61,7 @@ Options: - -e, --env value Set environment variables (default []) - --env-file value Read in a file of environment variables (default []) - --expose value Expose a port or a range of ports (default []) -+ --files-limit int Tune container files limit (set -1 for unlimited) - --group-add value Add additional groups to join (default []) - --health-cmd string Command to run to check health - --health-interval duration Time between running the check (ns|us|ms|s|m|h) (default 0s) -diff --git a/components/cli/man/docker-run.1.md b/components/cli/man/docker-run.1.md -index e03377001d..41f501d5b9 100644 ---- a/components/cli/man/docker-run.1.md -+++ b/components/cli/man/docker-run.1.md -@@ -39,6 +39,7 @@ docker-run - Run a command in a new container - [**--entrypoint**[=*ENTRYPOINT*]] - [**--env-file**[=*[]*]] - [**--expose**[=*[]*]] -+[**--files-limit**[=*FILES_LIMIT*]] - [**--group-add**[=*[]*]] - [**-h**|**--hostname**[=*HOSTNAME*]] - [**--help**] -@@ -315,6 +316,9 @@ that the container listens on the specified network ports at runtime. Docker - uses this information to interconnect containers using links and to set up port - redirection on the host system. - -+**--files-limit**="" -+ Tune the container's files limit. Set `-1` to have max files for the container. -+ - **--group-add**=[] - Add additional groups to run as - -diff --git a/components/cli/vendor/github.com/docker/docker/api/Checklist b/components/cli/vendor/github.com/docker/docker/api/Checklist -new file mode 100644 -index 0000000000..9594f235e4 ---- /dev/null -+++ b/components/cli/vendor/github.com/docker/docker/api/Checklist -@@ -0,0 +1 @@ -+Add FilesLimit to components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go for supporting --files-limit -diff --git a/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go b/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go -index 4ef26fa6c8..1565b5e091 100644 ---- a/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go -+++ b/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go -@@ -334,6 +334,7 @@ type Resources struct { - MemorySwappiness *int64 // Tuning container memory swappiness behaviour - OomKillDisable *bool // Whether to disable OOM Killer or not - PidsLimit int64 // Setting pids limit for a container -+ FilesLimit int64 // Setting files limit for a container - Ulimits []*units.Ulimit // List of ulimits to be set in the container - - // Applicable to Windows -diff --git a/components/engine/api/types/container/host_config.go b/components/engine/api/types/container/host_config.go -index 4ef26fa6c8..1565b5e091 100644 ---- a/components/engine/api/types/container/host_config.go -+++ b/components/engine/api/types/container/host_config.go -@@ -334,6 +334,7 @@ type Resources struct { - MemorySwappiness *int64 // Tuning container memory swappiness behaviour - OomKillDisable *bool // Whether to disable OOM Killer or not - PidsLimit int64 // Setting pids limit for a container -+ FilesLimit int64 // Setting files limit for a container - Ulimits []*units.Ulimit // List of ulimits to be set in the container - - // Applicable to Windows -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index 1b35df4950..138b8ac544 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -425,6 +425,12 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi - resources.PidsLimit = 0 - } - -+ if resources.FilesLimit != 0 && !sysInfo.FilesLimit { -+ warnings = append(warnings, "Your kernel does not support files limit capabilities, files limit discarded.") -+ logrus.Warnf("Your kernel does not support files limit capabilities, files limit discarded.") -+ resources.FilesLimit = 0 -+ } -+ - // cpu subsystem checks and adjustments - if resources.NanoCPUs > 0 && resources.CPUPeriod > 0 { - return warnings, fmt.Errorf("Conflicting options: Nano CPUs and CPU Period cannot both be set") -diff --git a/components/engine/daemon/oci_linux.go b/components/engine/daemon/oci_linux.go -index 864d22fbcb..210d2ad3f6 100644 ---- a/components/engine/daemon/oci_linux.go -+++ b/components/engine/daemon/oci_linux.go -@@ -70,6 +70,9 @@ func setResources(s *specs.Spec, r containertypes.Resources) error { - Pids: &specs.LinuxPids{ - Limit: r.PidsLimit, - }, -+ Files: &specs.Files{ -+ Limit: &r.FilesLimit, -+ }, - } - - if s.Linux.Resources != nil && len(s.Linux.Resources.Devices) > 0 { -diff --git a/components/engine/integration-cli/docker_cli_run_unix_test.go b/components/engine/integration-cli/docker_cli_run_unix_test.go -index 5f782ee530..a618316d4b 100644 ---- a/components/engine/integration-cli/docker_cli_run_unix_test.go -+++ b/components/engine/integration-cli/docker_cli_run_unix_test.go -@@ -1414,6 +1414,16 @@ func (s *DockerSuite) TestRunPIDsLimit(c *check.C) { - c.Assert(out, checker.Equals, "4", check.Commentf("setting the pids limit failed")) - } - -+// TestRunFilesLimit makes sure the files cgroup is set with --files-limit -+func (s *DockerSuite) TestRunFilesLimit(c *check.C) { -+ testRequires(c, filesLimit) -+ file := "/sys/fs/cgroup/files/files.limit" -+ out, _ := dockerCmd(c, "run", "--name", "fileslimit", "--files-limit", "32", "busybox", "cat", file) -+ c.Assert(strings.TrimSpace(out), checker.Equals, "32") -+ out = inspectField(c, "fileslimit", "HostConfig.FilesLimit") -+ c.Assert(out, checker.Equals, "32", check.Commentf("setting the files limit failed")) -+} -+ - func (s *DockerSuite) TestRunPrivilegedAllowedDevices(c *check.C) { - testRequires(c, DaemonIsLinux, NotUserNamespace) - -diff --git a/components/engine/integration-cli/requirements_unix_test.go b/components/engine/integration-cli/requirements_unix_test.go -index 7c594f7db4..873c1fbfe2 100644 ---- a/components/engine/integration-cli/requirements_unix_test.go -+++ b/components/engine/integration-cli/requirements_unix_test.go -@@ -37,6 +37,10 @@ func pidsLimit() bool { - return SysInfo.PidsLimit - } - -+func filesLimit() bool { -+ return SysInfo.FilesLimit -+} -+ - func kernelMemorySupport() bool { - return testEnv.DaemonInfo.KernelMemory - } -diff --git a/components/engine/pkg/sysinfo/sysinfo.go b/components/engine/pkg/sysinfo/sysinfo.go -index 0f327d5068..5d9320218c 100644 ---- a/components/engine/pkg/sysinfo/sysinfo.go -+++ b/components/engine/pkg/sysinfo/sysinfo.go -@@ -15,6 +15,7 @@ type SysInfo struct { - cgroupBlkioInfo - cgroupCpusetInfo - cgroupPids -+ cgroupFiles - - // Whether IPv4 forwarding is supported or not, if this was disabled, networking will not work - IPv4ForwardingDisabled bool -@@ -102,6 +103,11 @@ type cgroupPids struct { - PidsLimit bool - } - -+type cgroupFiles struct { -+ // Whether Files Limit is supported or not -+ FilesLimit bool -+} -+ - // IsCpusetCpusAvailable returns `true` if the provided string set is contained - // in cgroup's cpuset.cpus set, `false` otherwise. - // If error is not nil a parsing error occurred. -diff --git a/components/engine/pkg/sysinfo/sysinfo_linux.go b/components/engine/pkg/sysinfo/sysinfo_linux.go -index dde5be19bc..c0bf280412 100644 ---- a/components/engine/pkg/sysinfo/sysinfo_linux.go -+++ b/components/engine/pkg/sysinfo/sysinfo_linux.go -@@ -40,6 +40,7 @@ func New(quiet bool) *SysInfo { - sysInfo.cgroupBlkioInfo = checkCgroupBlkioInfo(cgMounts, quiet) - sysInfo.cgroupCpusetInfo = checkCgroupCpusetInfo(cgMounts, quiet) - sysInfo.cgroupPids = checkCgroupPids(quiet) -+ sysInfo.cgroupFiles = checkCgroupFiles(quiet) - } - - _, ok := cgMounts["devices"] -@@ -240,6 +241,20 @@ func checkCgroupPids(quiet bool) cgroupPids { - } - } - -+// checkCgroupPids reads the files information from the pids cgroup mount point. -+func checkCgroupFiles(quiet bool) cgroupFiles { -+ _, err := cgroups.FindCgroupMountpoint("files") -+ if err != nil { -+ if !quiet { -+ logrus.Warn(err) -+ } -+ return cgroupFiles{} -+ } -+ return cgroupFiles{ -+ FilesLimit: true, -+ } -+} -+ - func cgroupEnabled(mountPoint, name string) bool { - _, err := os.Stat(path.Join(mountPoint, name)) - return err == nil -diff --git a/components/engine/vendor/github.com/opencontainers/runtime-spec/Checklist b/components/engine/vendor/github.com/opencontainers/runtime-spec/Checklist -new file mode 100644 -index 0000000000..5b7ba2fab9 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runtime-spec/Checklist -@@ -0,0 +1 @@ -+Add struct LinuxFiles to components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go for supporting --files-limit -diff --git a/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go -index f32698cab2..46049b3bfa 100644 ---- a/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go -+++ b/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go -@@ -314,6 +314,12 @@ type LinuxPids struct { - Limit int64 `json:"limit"` - } - -+// Files for Linux cgroup 'files' resource management (https://lwn.net/Articles/604129/) -+type Files struct { -+ // Maximum number of open files. Default is "no limit". -+ Limit *int64 `json:"limit,omitempty"` -+} -+ - // LinuxNetwork identification and priority configuration - type LinuxNetwork struct { - // Set class identifier for container's network packets -@@ -340,6 +346,8 @@ type LinuxResources struct { - CPU *LinuxCPU `json:"cpu,omitempty"` - // Task resource restriction configuration. - Pids *LinuxPids `json:"pids,omitempty"` -+ // Files resource restriction configuration. -+ Files *Files `json:"files,omitempty"` - // BlockIO restriction configuration - BlockIO *LinuxBlockIO `json:"blockIO,omitempty"` - // Hugetlb limit (in bytes) --- -2.17.1 - diff --git a/patch/0008-filelimit-Ignore-host-kernel-whether-suport-f.patch b/patch/0008-filelimit-Ignore-host-kernel-whether-suport-f.patch deleted file mode 100644 index db1f0d6..0000000 --- a/patch/0008-filelimit-Ignore-host-kernel-whether-suport-f.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 7a965f7491e5f60e27ce1f6c052aa139f80e0744 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:14:42 +0800 -Subject: [PATCH 008/111] filelimit: Ignore host kernel whether suport - files limit when run a secure container - -reason:Ignore host kernel whether suport files limit when run a secure -container. - -Change-Id: Iabd2c54492465a8df53375206d5ff600d9da7f6e -Signed-off-by: yangshukui -Signed-off-by: lujingxiao ---- - components/engine/daemon/container.go | 2 +- - components/engine/daemon/daemon_unix.go | 15 +++++++++------ - components/engine/daemon/daemon_windows.go | 6 +++--- - 3 files changed, 13 insertions(+), 10 deletions(-) - -diff --git a/components/engine/daemon/container.go b/components/engine/daemon/container.go -index c8e2053970..bd96de2571 100644 ---- a/components/engine/daemon/container.go -+++ b/components/engine/daemon/container.go -@@ -348,7 +348,7 @@ func (daemon *Daemon) verifyContainerSettings(platform string, hostConfig *conta - warnings []string - ) - // Now do platform-specific verification -- if warnings, err = verifyPlatformContainerSettings(daemon, hostConfig, config, update); err != nil { -+ if warnings, err = daemon.verifyPlatformContainerSettings(hostConfig, config, update); err != nil { - return warnings, err - } - if hostConfig.NetworkMode.IsHost() && len(hostConfig.PortBindings) > 0 { -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index 138b8ac544..f4b75055f5 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -350,8 +350,9 @@ func adaptSharedNamespaceContainer(daemon containerGetter, hostConfig *container - } - } - --func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysinfo.SysInfo, update bool) ([]string, error) { -+func (daemon *Daemon) verifyContainerResources(hostConfig *containertypes.HostConfig, sysInfo *sysinfo.SysInfo, update bool) ([]string, error) { - warnings := []string{} -+ resources := &hostConfig.Resources - fixMemorySwappiness(resources) - - // memory subsystem checks and adjustments -@@ -426,9 +427,11 @@ func verifyContainerResources(resources *containertypes.Resources, sysInfo *sysi - } - - if resources.FilesLimit != 0 && !sysInfo.FilesLimit { -- warnings = append(warnings, "Your kernel does not support files limit capabilities, files limit discarded.") -- logrus.Warnf("Your kernel does not support files limit capabilities, files limit discarded.") -- resources.FilesLimit = 0 -+ if daemon.IsNativeRuntime(hostConfig.Runtime) { -+ warnings = append(warnings, "Your kernel does not support files limit capabilities, files limit discarded.") -+ logrus.Warnf("Your kernel does not support files limit capabilities, files limit discarded.") -+ resources.FilesLimit = 0 -+ } - } - - // cpu subsystem checks and adjustments -@@ -580,11 +583,11 @@ func UsingSystemd(config *config.Config) bool { - - // verifyPlatformContainerSettings performs platform-specific validation of the - // hostconfig and config structures. --func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) { -+func (daemon *Daemon) verifyPlatformContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) { - var warnings []string - sysInfo := sysinfo.New(true) - -- w, err := verifyContainerResources(&hostConfig.Resources, sysInfo, update) -+ w, err := daemon.verifyContainerResources(hostConfig, sysInfo, update) - - // no matter err is nil or not, w could have data in itself. - warnings = append(warnings, w...) -diff --git a/components/engine/daemon/daemon_windows.go b/components/engine/daemon/daemon_windows.go -index 04d3de9924..4812236bc2 100644 ---- a/components/engine/daemon/daemon_windows.go -+++ b/components/engine/daemon/daemon_windows.go -@@ -75,7 +75,7 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf - return nil - } - --func verifyContainerResources(resources *containertypes.Resources, isHyperv bool) ([]string, error) { -+func (daemon *Daemon) verifyContainerResources(resources *containertypes.Resources, isHyperv bool) ([]string, error) { - warnings := []string{} - fixMemorySwappiness(resources) - if !isHyperv { -@@ -191,10 +191,10 @@ func verifyContainerResources(resources *containertypes.Resources, isHyperv bool - - // verifyPlatformContainerSettings performs platform-specific validation of the - // hostconfig and config structures. --func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) { -+func (daemon *Daemon) verifyPlatformContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) { - warnings := []string{} - -- hyperv := daemon.runAsHyperVContainer(hostConfig) -+ hyperv := daemon.daemon.runAsHyperVContainer(hostConfig) - if !hyperv && system.IsWindowsClient() && !system.IsIoTCore() { - // @engine maintainers. This block should not be removed. It partially enforces licensing - // restrictions on Windows. Ping @jhowardmsft if there are concerns or PRs to change this. --- -2.17.1 - diff --git a/patch/0009-healthycheck-add-healthycheck-in-_ping-add-se.patch b/patch/0009-healthycheck-add-healthycheck-in-_ping-add-se.patch deleted file mode 100644 index a07f0cb..0000000 --- a/patch/0009-healthycheck-add-healthycheck-in-_ping-add-se.patch +++ /dev/null @@ -1,128 +0,0 @@ -From c03a609c9bb837d8f361888460c7a605dc1219d6 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:15:11 +0800 -Subject: [PATCH 009/111] healthycheck: add healthycheck in _ping & - add semaphore set info in docker info - -reason: add healthycheck in _ping & add semaphore set info in docker info - -Change-Id: I90b3def5fa8bcf0e21090471c43c6309e58c26aa -Signed-off-by: liruilin4 -Signed-off-by: zhangyu235 -Signed-off-by: lujingxiao ---- - .../api/server/router/system/backend.go | 1 + - .../api/server/router/system/system_routes.go | 2 ++ - .../daemon/graphdriver/devmapper/driver.go | 7 ++++++ - components/engine/daemon/info.go | 10 ++++++++ - components/engine/utils/utils.go | 23 +++++++++++++++++++ - 5 files changed, 43 insertions(+) - create mode 100644 components/engine/utils/utils.go - -diff --git a/components/engine/api/server/router/system/backend.go b/components/engine/api/server/router/system/backend.go -index f5d2d98101..2ba5ab774b 100644 ---- a/components/engine/api/server/router/system/backend.go -+++ b/components/engine/api/server/router/system/backend.go -@@ -19,6 +19,7 @@ type Backend interface { - SubscribeToEvents(since, until time.Time, ef filters.Args) ([]events.Message, chan interface{}) - UnsubscribeFromEvents(chan interface{}) - AuthenticateToRegistry(ctx context.Context, authConfig *types.AuthConfig) (string, string, error) -+ HealthyCheck() - } - - // ClusterBackend is all the methods that need to be implemented -diff --git a/components/engine/api/server/router/system/system_routes.go b/components/engine/api/server/router/system/system_routes.go -index a2ff692de3..f235acc657 100644 ---- a/components/engine/api/server/router/system/system_routes.go -+++ b/components/engine/api/server/router/system/system_routes.go -@@ -31,6 +31,8 @@ func (s *systemRouter) pingHandler(ctx context.Context, w http.ResponseWriter, r - if bv := builderVersion; bv != "" { - w.Header().Set("Builder-Version", string(bv)) - } -+ -+ s.backend.HealthyCheck() - _, err := w.Write([]byte{'O', 'K'}) - return err - } -diff --git a/components/engine/daemon/graphdriver/devmapper/driver.go b/components/engine/daemon/graphdriver/devmapper/driver.go -index 899b1f8670..623843f852 100644 ---- a/components/engine/daemon/graphdriver/devmapper/driver.go -+++ b/components/engine/daemon/graphdriver/devmapper/driver.go -@@ -15,6 +15,7 @@ import ( - "github.com/docker/docker/pkg/idtools" - "github.com/docker/docker/pkg/locker" - "github.com/docker/docker/pkg/mount" -+ "github.com/docker/docker/utils" - "github.com/docker/go-units" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -@@ -101,6 +102,12 @@ func (d *Driver) Status() [][2]string { - if vStr, err := devicemapper.GetLibraryVersion(); err == nil { - status = append(status, [2]string{"Library Version", vStr}) - } -+ usz, mni, err := utils.CheckSemSetStat() -+ status = append(status, [2]string{"Semaphore Set Used", fmt.Sprintf("%d", usz)}) -+ status = append(status, [2]string{"Semaphore Set Total", fmt.Sprintf("%d", mni)}) -+ if err != nil { -+ status = append(status, [2]string{"WARNING", fmt.Sprintf("%v", err)}) -+ } - return status - } - -diff --git a/components/engine/daemon/info.go b/components/engine/daemon/info.go -index bf84342b54..262719d9d1 100644 ---- a/components/engine/daemon/info.go -+++ b/components/engine/daemon/info.go -@@ -20,6 +20,7 @@ import ( - "github.com/docker/docker/pkg/sysinfo" - "github.com/docker/docker/pkg/system" - "github.com/docker/docker/registry" -+ "github.com/docker/docker/utils" - "github.com/docker/go-connections/sockets" - "github.com/sirupsen/logrus" - ) -@@ -256,3 +257,12 @@ func maskCredentials(rawURL string) string { - maskedURL := parsedURL.String() - return maskedURL - } -+ -+func (daemon *Daemon) HealthyCheck() { -+ if daemon.imageService.GraphDriverForOS(runtime.GOOS) == "devicemapper" { -+ _, _, err := utils.CheckSemSetStat() -+ if err != nil { -+ logrus.Warn(err) -+ } -+ } -+} -diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go -new file mode 100644 -index 0000000000..75fd409399 ---- /dev/null -+++ b/components/engine/utils/utils.go -@@ -0,0 +1,23 @@ -+package utils -+ -+/* -+#include -+#include -+int mysemctl(int cmd, struct seminfo *p){ -+ return semctl(0, 0, cmd, p); -+} -+*/ -+import "C" -+import ( -+ "fmt" -+) -+ -+func CheckSemSetStat() (int, int, error) { -+ var seminfo *C.struct_seminfo = new(C.struct_seminfo) -+ C.mysemctl(C.SEM_INFO, seminfo) -+ var err error = nil -+ if seminfo.semusz == seminfo.semmni { -+ err = fmt.Errorf("system semaphore nums has attached limit: %d", int(seminfo.semusz)) -+ } -+ return int(seminfo.semusz), int(seminfo.semmni), err -+} --- -2.17.1 - diff --git a/patch/0010-annotation-add-annotation-into-cli-flag.patch b/patch/0010-annotation-add-annotation-into-cli-flag.patch deleted file mode 100644 index 2b3238f..0000000 --- a/patch/0010-annotation-add-annotation-into-cli-flag.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 961d5e98090e4725dca298dde8afb8df54f99f2e Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:15:25 +0800 -Subject: [PATCH 010/111] annotation: add annotation into cli flag - -reason: add annotation into cli flag - -Change-Id: Ibca64819e6f390c70e8516a1462d8e465fcfe080 -Signed-off-by: caihaomin -Signed-off-by: lujingxiao ---- - components/cli/cli/command/container/opts.go | 7 +++++ - .../docker/api/types/container/config.go | 1 + - .../engine/api/types/container/config.go | 1 + - components/engine/api/types/types.go | 28 ++++++++++--------- - components/engine/daemon/oci_linux.go | 1 + - 5 files changed, 25 insertions(+), 13 deletions(-) - -diff --git a/components/cli/cli/command/container/opts.go b/components/cli/cli/command/container/opts.go -index efb28a2cdf..af30dfcbf2 100644 ---- a/components/cli/cli/command/container/opts.go -+++ b/components/cli/cli/command/container/opts.go -@@ -43,6 +43,7 @@ type containerOptions struct { - deviceWriteIOps opts.ThrottledeviceOpt - env opts.ListOpts - labels opts.ListOpts -+ annotation opts.ListOpts - deviceCgroupRules opts.ListOpts - devices opts.ListOpts - ulimits *opts.UlimitOpt -@@ -148,6 +149,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { - groupAdd: opts.NewListOpts(nil), - labels: opts.NewListOpts(nil), - labelsFile: opts.NewListOpts(nil), -+ annotation: opts.NewListOpts(opts.ValidateEnv), - linkLocalIPs: opts.NewListOpts(nil), - links: opts.NewListOpts(opts.ValidateLink), - loggingOpts: opts.NewListOpts(nil), -@@ -173,6 +175,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { - flags.BoolVarP(&copts.stdin, "interactive", "i", false, "Keep STDIN open even if not attached") - flags.VarP(&copts.labels, "label", "l", "Set meta data on a container") - flags.Var(&copts.labelsFile, "label-file", "Read in a line delimited file of labels") -+ flags.Var(&copts.annotation, "annotation", "Set annotations on a container") - flags.BoolVar(&copts.readonlyRootfs, "read-only", false, "Mount the container's root filesystem as read only") - flags.StringVar(&copts.restartPolicy, "restart", "no", "Restart policy to apply when a container exits") - flags.StringVar(&copts.stopSignal, "stop-signal", signal.DefaultStopSignal, "Signal to stop a container") -@@ -438,6 +441,9 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err - return nil, err - } - -+ // collect all the annotations for the container -+ annotations := copts.annotation.GetAll() -+ - pidMode := container.PidMode(copts.pidMode) - if !pidMode.Valid() { - return nil, errors.Errorf("--pid: invalid PID mode") -@@ -568,6 +574,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err - Entrypoint: entrypoint, - WorkingDir: copts.workingDir, - Labels: opts.ConvertKVStringsToMap(labels), -+ Annotations: opts.ConvertKVStringsToMap(annotations), - Healthcheck: healthConfig, - } - if flags.Changed("stop-signal") { -diff --git a/components/cli/vendor/github.com/docker/docker/api/types/container/config.go b/components/cli/vendor/github.com/docker/docker/api/types/container/config.go -index 89ad08c234..c28f0b101e 100644 ---- a/components/cli/vendor/github.com/docker/docker/api/types/container/config.go -+++ b/components/cli/vendor/github.com/docker/docker/api/types/container/config.go -@@ -63,6 +63,7 @@ type Config struct { - MacAddress string `json:",omitempty"` // Mac Address of the container - OnBuild []string // ONBUILD metadata that were defined on the image Dockerfile - Labels map[string]string // List of labels set to this container -+ Annotations map[string]string // List of annotations set to this container - StopSignal string `json:",omitempty"` // Signal to stop a container - StopTimeout *int `json:",omitempty"` // Timeout (in seconds) to stop a container - Shell strslice.StrSlice `json:",omitempty"` // Shell for shell-form of RUN, CMD, ENTRYPOINT -diff --git a/components/engine/api/types/container/config.go b/components/engine/api/types/container/config.go -index 89ad08c234..c28f0b101e 100644 ---- a/components/engine/api/types/container/config.go -+++ b/components/engine/api/types/container/config.go -@@ -63,6 +63,7 @@ type Config struct { - MacAddress string `json:",omitempty"` // Mac Address of the container - OnBuild []string // ONBUILD metadata that were defined on the image Dockerfile - Labels map[string]string // List of labels set to this container -+ Annotations map[string]string // List of annotations set to this container - StopSignal string `json:",omitempty"` // Signal to stop a container - StopTimeout *int `json:",omitempty"` // Timeout (in seconds) to stop a container - Shell strslice.StrSlice `json:",omitempty"` // Shell for shell-form of RUN, CMD, ENTRYPOINT -diff --git a/components/engine/api/types/types.go b/components/engine/api/types/types.go -index a8fae3ba32..959e9eb447 100644 ---- a/components/engine/api/types/types.go -+++ b/components/engine/api/types/types.go -@@ -56,19 +56,20 @@ type ImageMetadata struct { - // Container contains response of Engine API: - // GET "/containers/json" - type Container struct { -- ID string `json:"Id"` -- Names []string -- Image string -- ImageID string -- Command string -- Created int64 -- Ports []Port -- SizeRw int64 `json:",omitempty"` -- SizeRootFs int64 `json:",omitempty"` -- Labels map[string]string -- State string -- Status string -- HostConfig struct { -+ ID string `json:"Id"` -+ Names []string -+ Image string -+ ImageID string -+ Command string -+ Created int64 -+ Ports []Port -+ SizeRw int64 `json:",omitempty"` -+ SizeRootFs int64 `json:",omitempty"` -+ Labels map[string]string -+ Annotaitons map[string]string -+ State string -+ Status string -+ HostConfig struct { - NetworkMode string `json:",omitempty"` - } - NetworkSettings *SummaryNetworkSettings -@@ -188,6 +189,7 @@ type Info struct { - NoProxy string - Name string - Labels []string -+ Annotations []string - ExperimentalBuild bool - ServerVersion string - ClusterStore string -diff --git a/components/engine/daemon/oci_linux.go b/components/engine/daemon/oci_linux.go -index 210d2ad3f6..5018b21f0d 100644 ---- a/components/engine/daemon/oci_linux.go -+++ b/components/engine/daemon/oci_linux.go -@@ -846,6 +846,7 @@ func (daemon *Daemon) createSpec(c *container.Container) (retSpec *specs.Spec, e - s.Process.NoNewPrivileges = c.NoNewPrivileges - s.Process.OOMScoreAdj = &c.HostConfig.OomScoreAdj - s.Linux.MountLabel = c.MountLabel -+ s.Annotations = c.Config.Annotations - - // Set the masked and readonly paths with regard to the host config options if they are set. - if c.HostConfig.MaskedPaths != nil { --- -2.17.1 - diff --git a/patch/0011-hookspec-Allow-adding-custom-hooks.patch b/patch/0011-hookspec-Allow-adding-custom-hooks.patch deleted file mode 100644 index 0b14502..0000000 --- a/patch/0011-hookspec-Allow-adding-custom-hooks.patch +++ /dev/null @@ -1,288 +0,0 @@ -From 65c782bb9b0b159f5644395cb291b8741b4400f4 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:15:40 +0800 -Subject: [PATCH 011/111] hookspec: Allow adding custom hooks - -reason: Add new flag "--hook-spec" which accept a file containing custom hook -definitions, custom hooks will be appended to system hooks which means -docker will execute its own hook first(libnetwork prestart hook) to make -sure everything predefined is working normally, user custom programme -can be executed afterwards - -One example hook spec file can be of format: -``` -{ - "prestart": [ - { - "path": "/bin/ls", - "args": ["ls"], - "env": [] - } - ], - "poststart":[], - "poststop":[] -} -``` - -Change-Id: Iee6f4e5b56ebf0647304c08c2948d599356192e6 -Signed-off-by: Zhang Wei -Signed-off-by: xiadanni -Signed-off-by: lujingxiao ---- - components/cli/cli/command/container/opts.go | 3 ++ - .../cli/docs/reference/commandline/create.md | 1 + - .../cli/docs/reference/commandline/run.md | 1 + - components/cli/man/docker-run.1.md | 28 +++++++++++++++++++ - .../docker/api/types/container/host_config.go | 1 + - .../engine/api/types/container/host_config.go | 1 + - components/engine/container/container.go | 4 ++- - components/engine/daemon/container.go | 24 ++++++++++++++++ - components/engine/daemon/daemon_unix.go | 16 +++++++++++ - components/engine/daemon/oci_linux.go | 6 ++++ - 10 files changed, 84 insertions(+), 1 deletion(-) - -diff --git a/components/cli/cli/command/container/opts.go b/components/cli/cli/command/container/opts.go -index af30dfcbf2..8e07aa77cb 100644 ---- a/components/cli/cli/command/container/opts.go -+++ b/components/cli/cli/command/container/opts.go -@@ -111,6 +111,7 @@ type containerOptions struct { - stopTimeout int - isolation string - shmSize opts.MemBytes -+ hookSpec string - noHealthcheck bool - healthCmd string - healthInterval time.Duration -@@ -283,6 +284,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { - flags.StringVar(&copts.isolation, "isolation", "", "Container isolation technology") - flags.StringVar(&copts.pidMode, "pid", "", "PID namespace to use") - flags.Var(&copts.shmSize, "shm-size", "Size of /dev/shm") -+ flags.StringVar(&copts.hookSpec, "hook-spec", "", "file containing hook definition(prestart, poststart, poststop)") - flags.StringVar(&copts.utsMode, "uts", "", "UTS namespace to use") - flags.StringVar(&copts.runtime, "runtime", "", "Runtime to use for this container") - -@@ -619,6 +621,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err - VolumeDriver: copts.volumeDriver, - Isolation: container.Isolation(copts.isolation), - ShmSize: copts.shmSize.Value(), -+ HookSpec: copts.hookSpec, - Resources: resources, - Tmpfs: tmpfs, - Sysctls: copts.sysctls.GetAll(), -diff --git a/components/cli/docs/reference/commandline/create.md b/components/cli/docs/reference/commandline/create.md -index 5d888183b3..34cb79a679 100644 ---- a/components/cli/docs/reference/commandline/create.md -+++ b/components/cli/docs/reference/commandline/create.md -@@ -66,6 +66,7 @@ Options: - --health-start-period duration Start period for the container to initialize before counting retries towards unstable (ns|us|ms|s|m|h) (default 0s) - --help Print usage - -h, --hostname string Container host name -+ --hook-spec File containing hook definition(prestart, poststart, poststop) - --init Run an init inside the container that forwards signals and reaps processes - -i, --interactive Keep STDIN open even if not attached - --io-maxbandwidth string Maximum IO bandwidth limit for the system drive (Windows only) -diff --git a/components/cli/docs/reference/commandline/run.md b/components/cli/docs/reference/commandline/run.md -index 21b4fdf261..1dc43ddcd9 100644 ---- a/components/cli/docs/reference/commandline/run.md -+++ b/components/cli/docs/reference/commandline/run.md -@@ -70,6 +70,7 @@ Options: - --health-start-period duration Start period for the container to initialize before counting retries towards unstable (ns|us|ms|s|m|h) (default 0s) - --help Print usage - -h, --hostname string Container host name -+ --hook-spec File containing hook definition(prestart, poststart, poststop) - --init Run an init inside the container that forwards signals and reaps processes - -i, --interactive Keep STDIN open even if not attached - --io-maxbandwidth string Maximum IO bandwidth limit for the system drive (Windows only) -diff --git a/components/cli/man/docker-run.1.md b/components/cli/man/docker-run.1.md -index 41f501d5b9..b0cbcd2e87 100644 ---- a/components/cli/man/docker-run.1.md -+++ b/components/cli/man/docker-run.1.md -@@ -43,6 +43,7 @@ docker-run - Run a command in a new container - [**--group-add**[=*[]*]] - [**-h**|**--hostname**[=*HOSTNAME*]] - [**--help**] -+[**--hook-spec**[=*HOOKFILE*]] - [**--init**] - [**-i**|**--interactive**] - [**--ip**[=*IPv4-ADDRESS*]] -@@ -330,6 +331,33 @@ redirection on the host system. - **--help** - Print usage statement - -+**--hook-spec**="" -+ Add custom hooks for container -+ -+ With this flag, user can specify a file containing custom hook, an example hook file can be like this: -+ -+``` -+{ -+ "prestart": [ -+ { -+ "path": "/usr/libexec/oci/hooks.d/oci-systemd-hook", -+ "args": ["oci-systemd-hook", "prestart"], -+ "env": ["container=runc"] -+ } -+ ], -+ "poststop":[ -+ { -+ "path": "/usr/libexec/oci/hooks.d/oci-systemd-hook", -+ "args": ["oci-systemd-hook", "poststop"], -+ "env": ["container=runc"] -+ } -+ ] -+} -+``` -+ -+ currently it supports three hooks: "prestart", "poststart", "poststop". -+ See OCI spec definition for more information about "hooks". -+ - **--init** - Run an init inside the container that forwards signals and reaps processes - -diff --git a/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go b/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go -index 1565b5e091..701cae55f1 100644 ---- a/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go -+++ b/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go -@@ -395,6 +395,7 @@ type HostConfig struct { - // Applicable to Windows - ConsoleSize [2]uint // Initial console size (height,width) - Isolation Isolation // Isolation technology of the container (e.g. default, hyperv) -+ HookSpec string // specification file containing custom hook definition - - // Contains container's resources (cgroups, ulimits) - Resources -diff --git a/components/engine/api/types/container/host_config.go b/components/engine/api/types/container/host_config.go -index 1565b5e091..701cae55f1 100644 ---- a/components/engine/api/types/container/host_config.go -+++ b/components/engine/api/types/container/host_config.go -@@ -395,6 +395,7 @@ type HostConfig struct { - // Applicable to Windows - ConsoleSize [2]uint // Initial console size (height,width) - Isolation Isolation // Isolation technology of the container (e.g. default, hyperv) -+ HookSpec string // specification file containing custom hook definition - - // Contains container's resources (cgroups, ulimits) - Resources -diff --git a/components/engine/container/container.go b/components/engine/container/container.go -index f74676f7ee..02adc2019a 100644 ---- a/components/engine/container/container.go -+++ b/components/engine/container/container.go -@@ -38,6 +38,7 @@ import ( - volumemounts "github.com/docker/docker/volume/mounts" - "github.com/docker/go-units" - agentexec "github.com/docker/swarmkit/agent/exec" -+ "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - ) -@@ -93,6 +94,8 @@ type Container struct { - LogCopier *logger.Copier `json:"-"` - restartManager restartmanager.RestartManager - attachContext *attachContext -+ Hooks specs.Hooks -+ CgroupParent string - - // Fields here are specific to Unix platforms - AppArmorProfile string -@@ -106,7 +109,6 @@ type Container struct { - // Fields here are specific to Windows - NetworkSharedContainerID string `json:"-"` - SharedEndpointList []string `json:"-"` -- CgroupParent string - } - - // NewBaseContainer creates a new container with its -diff --git a/components/engine/daemon/container.go b/components/engine/daemon/container.go -index bd96de2571..8e68904b16 100644 ---- a/components/engine/daemon/container.go -+++ b/components/engine/daemon/container.go -@@ -1,6 +1,7 @@ - package daemon // import "github.com/docker/docker/daemon" - - import ( -+ "encoding/json" - "fmt" - "os" - "path" -@@ -224,11 +225,34 @@ func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig * - return err - } - -+ // register hooks to container -+ if err := daemon.registerHooks(container, hostConfig); err != nil { -+ return err -+ } -+ - runconfig.SetDefaultNetModeIfBlank(hostConfig) - container.HostConfig = hostConfig - return container.CheckpointTo(daemon.containersReplica) - } - -+ -+func (daemon *Daemon) registerHooks(container *container.Container, hostConfig *containertypes.HostConfig) error { -+ if hostConfig.HookSpec == "" { -+ return nil -+ } -+ // the hook spec has already been sanitized, so no need for validation again -+ f, err := os.Open(hostConfig.HookSpec) -+ if err != nil { -+ return fmt.Errorf("open hook spec file error: %v", err) -+ } -+ defer f.Close() -+ -+ if err = json.NewDecoder(f).Decode(&container.Hooks); err != nil { -+ return fmt.Errorf("malformed hook spec, is your spec file in json format? error: %v", err) -+ } -+ return nil -+} -+ - // verifyContainerSettings performs validation of the hostconfig and config - // structures. - func (daemon *Daemon) verifyContainerSettings(platform string, hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) { -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index f4b75055f5..ebf4e067fb 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -627,6 +627,22 @@ func (daemon *Daemon) verifyPlatformContainerSettings(hostConfig *containertypes - return warnings, fmt.Errorf("cgroup-parent for systemd cgroup should be a valid slice named as \"xxx.slice\"") - } - } -+ -+ if hostConfig.HookSpec != "" { -+ hostConfig.HookSpec = filepath.Clean(hostConfig.HookSpec) -+ if !filepath.IsAbs(hostConfig.HookSpec) { -+ return warnings, fmt.Errorf("Hook spec file must be an absolute path") -+ } -+ fi, err := os.Stat(hostConfig.HookSpec) -+ if err != nil { -+ return warnings, fmt.Errorf("stat hook spec file failed: %v", err) -+ } -+ if !fi.Mode().IsRegular() { -+ return warnings, fmt.Errorf("Hook spec file must be a regular text file") -+ } -+ } -+ -+ - if hostConfig.Runtime == "" { - hostConfig.Runtime = daemon.configStore.GetDefaultRuntimeName() - } -diff --git a/components/engine/daemon/oci_linux.go b/components/engine/daemon/oci_linux.go -index 5018b21f0d..884739c07e 100644 ---- a/components/engine/daemon/oci_linux.go -+++ b/components/engine/daemon/oci_linux.go -@@ -818,6 +818,12 @@ func (daemon *Daemon) createSpec(c *container.Container) (retSpec *specs.Spec, e - } - } - -+ // apppend user custom hooks after system hooks -+ // make sure docker's predefined hooks are executed before custom hooks -+ s.Hooks.Prestart = append(s.Hooks.Prestart, c.Hooks.Prestart...) -+ s.Hooks.Poststart = append(s.Hooks.Poststart, c.Hooks.Poststart...) -+ s.Hooks.Poststop = append(s.Hooks.Poststop, c.Hooks.Poststop...) -+ - if apparmor.IsEnabled() { - var appArmorProfile string - if c.AppArmorProfile != "" { --- -2.17.1 - diff --git a/patch/0012-hookspec-Security-enhancement-for-hooks.patch b/patch/0012-hookspec-Security-enhancement-for-hooks.patch deleted file mode 100644 index 3bce41d..0000000 --- a/patch/0012-hookspec-Security-enhancement-for-hooks.patch +++ /dev/null @@ -1,82 +0,0 @@ -From e81d103000ae3213b91ed54410ddb20d911ddc1a Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:15:56 +0800 -Subject: [PATCH 012/111] hookspec: Security enhancement for hooks - -reason: Currently docker support running hooks with any path, this is insecure. -To solve this, we need to restrict path to specified path, e.g. -"/var/lib/docker/hooks" or "/var/lib/docker/1000.1000/hooks" if user -remap enabled for user ns. - -Change-Id: I9cff78f1a1105dcb4bc0b00c8e6e715904dfb778 -Signed-off-by: Zhang Wei -Signed-off-by: xiadanni -Signed-off-by: lujingxiao ---- - components/engine/daemon/container.go | 37 +++++++++++++++++++++++++++ - components/engine/daemon/daemon.go | 1 + - 2 files changed, 38 insertions(+) - -diff --git a/components/engine/daemon/container.go b/components/engine/daemon/container.go -index 8e68904b16..0864443513 100644 ---- a/components/engine/daemon/container.go -+++ b/components/engine/daemon/container.go -@@ -250,6 +250,43 @@ func (daemon *Daemon) registerHooks(container *container.Container, hostConfig * - if err = json.NewDecoder(f).Decode(&container.Hooks); err != nil { - return fmt.Errorf("malformed hook spec, is your spec file in json format? error: %v", err) - } -+ -+ // hook path must be absolute and must be subdir of XXX -+ if err = daemon.validateHook(container); err != nil { -+ return err -+ } -+ return nil -+} -+ -+func (daemon *Daemon) validateHook(container *container.Container) error { -+ for _, v := range container.Hooks.Prestart { -+ if err := daemon.validateHookPath(v.Path); err != nil { -+ return err -+ } -+ } -+ for _, v := range container.Hooks.Poststart { -+ if err := daemon.validateHookPath(v.Path); err != nil { -+ return err -+ } -+ } -+ for _, v := range container.Hooks.Poststop { -+ if err := daemon.validateHookPath(v.Path); err != nil { -+ return err -+ } -+ } -+ return nil -+} -+ -+func (daemon *Daemon) validateHookPath(path string) error { -+ // hook path must be absolute and must be subdir of XXX -+ path = filepath.Clean(path) -+ if !filepath.IsAbs(path) { -+ return fmt.Errorf("Hook path %q must be an absolute path", path) -+ } -+ -+ if !filepath.HasPrefix(path, daemon.hookStore) { -+ return fmt.Errorf("hook program must be put under %q", daemon.hookStore) -+ } - return nil - } - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 8d6b4d8546..d1f3131c4f 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -95,6 +95,7 @@ type Daemon struct { - volumes *volumesservice.VolumesService - discoveryWatcher discovery.Reloader - root string -+ hookStore string - seccompEnabled bool - apparmorEnabled bool - shutdown bool --- -2.17.1 - diff --git a/patch/0013-hookspec-Add-bash-completion-for-hook-spec.patch b/patch/0013-hookspec-Add-bash-completion-for-hook-spec.patch deleted file mode 100644 index 60cfac0..0000000 --- a/patch/0013-hookspec-Add-bash-completion-for-hook-spec.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e261cd646bd656db1eae5a3bcb4af59af3423a46 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:16:09 +0800 -Subject: [PATCH 013/111] hookspec: Add bash completion for - --hook-spec - -reason: Add bash completion for --hook-spec - -Change-Id: Ic2cf226576a5437aa69b48edb73737c59f116ae8 -Signed-off-by: Zhang Wei -Signed-off-by: xiadanni -Signed-off-by: lujingxiao ---- - components/cli/contrib/completion/bash/docker | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker -index 2e2c8cb04f..9012988075 100644 ---- a/components/cli/contrib/completion/bash/docker -+++ b/components/cli/contrib/completion/bash/docker -@@ -1791,6 +1791,7 @@ _docker_container_run_and_create() { - --expose - --files-limit - --group-add -+ --hook-spec - --health-cmd - --health-interval - --health-retries --- -2.17.1 - diff --git a/patch/0014-hookspec-Add-default-hooks-for-all-containers.patch b/patch/0014-hookspec-Add-default-hooks-for-all-containers.patch deleted file mode 100644 index e253458..0000000 --- a/patch/0014-hookspec-Add-default-hooks-for-all-containers.patch +++ /dev/null @@ -1,367 +0,0 @@ -From d6725e951ee958b61af8c32d5c71d79d2e708432 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:16:48 +0800 -Subject: [PATCH 014/111] hookspec: Add default hooks for all - containers - -reason: Add new flag `--hook-spec` for daemon, so that we can specify one json -file containing hooks definition for all containers. - -You can also add this into `/etc/docker/daemon.json` daemon config file: - -``` -{ - "hook-spec": "/tmp/hookspec.json" -} -``` - -Change-Id: I9263d5a912daeb04621e7d2ec991204333c2b931 -Signed-off-by: Zhang Wei -Signed-off-by: xiadanni -Signed-off-by: lujingxiao ---- - components/cli/cli/command/system/info.go | 4 + - components/cli/contrib/completion/bash/docker | 1 + - .../cli/docs/reference/commandline/dockerd.md | 1 + - components/cli/man/dockerd.8.md | 25 ++++- - .../docker/docker/api/types/types.go | 1 + - components/engine/api/types/types.go | 1 + - components/engine/cmd/dockerd/config.go | 1 + - components/engine/daemon/config/config.go | 1 + - components/engine/daemon/container.go | 94 +++++++++++++++++-- - components/engine/daemon/daemon.go | 7 ++ - components/engine/daemon/info.go | 1 + - 11 files changed, 126 insertions(+), 11 deletions(-) - -diff --git a/components/cli/cli/command/system/info.go b/components/cli/cli/command/system/info.go -index 92fc2cd3e7..17ccc14aec 100644 ---- a/components/cli/cli/command/system/info.go -+++ b/components/cli/cli/command/system/info.go -@@ -204,6 +204,10 @@ func prettyPrintInfo(dockerCli command.Cli, info types.Info) error { - } - - fmt.Fprintln(dockerCli.Out(), "Live Restore Enabled:", info.LiveRestoreEnabled) -+ if info.HookSpec != "" { -+ fmt.Fprintf(dockerCli.Out(), "Default hook spec file: %s", info.HookSpec) -+ } -+ - if info.ProductLicense != "" { - fmt.Fprintln(dockerCli.Out(), "Product License:", info.ProductLicense) - } -diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker -index 9012988075..64f7fe08dd 100644 ---- a/components/cli/contrib/completion/bash/docker -+++ b/components/cli/contrib/completion/bash/docker -@@ -2274,6 +2274,7 @@ _docker_daemon() { - --fixed-cidr - --fixed-cidr-v6 - --group -G -+ --hook-spec - --init-path - --insecure-registry - --ip -diff --git a/components/cli/docs/reference/commandline/dockerd.md b/components/cli/docs/reference/commandline/dockerd.md -index 4b50b78b19..bbf6908af3 100644 ---- a/components/cli/docs/reference/commandline/dockerd.md -+++ b/components/cli/docs/reference/commandline/dockerd.md -@@ -53,6 +53,7 @@ Options: - --fixed-cidr-v6 string IPv6 subnet for fixed IPs - -G, --group string Group for the unix socket (default "docker") - --help Print usage -+ --hook-spec Default hook spec file applied to all containers - -H, --host list Daemon socket(s) to connect to (default []) - --icc Enable inter-container communication (default true) - --init Run an init in the container to forward signals and reap processes -diff --git a/components/cli/man/dockerd.8.md b/components/cli/man/dockerd.8.md -index 0224035970..d075080e78 100644 ---- a/components/cli/man/dockerd.8.md -+++ b/components/cli/man/dockerd.8.md -@@ -38,6 +38,7 @@ dockerd - Enable daemon mode - [**-G**|**--group**[=*docker*]] - [**-H**|**--host**[=*[]*]] - [**--help**] -+[**--hook-spec**[=*HOOKFILE*]] - [**--icc**[=*true*]] - [**--init**[=*false*]] - [**--init-path**[=*""*]] -@@ -239,7 +240,29 @@ unix://[/path/to/socket] to use. - - **--help** - Print usage statement -- -+ -+**--hook-spec**="" -+ Add default hooks for all containers. -+ -+ With this flag, user can specify a file containing custom hook, an example hook file can be like this: -+ -+ ``` -+ { -+ "prestart": [ -+ { -+ "path": "/var/lib/docker/hooks/myhook", -+ "args": ["myhook", "prestart"], -+ "env": ["container=runc"] -+ } -+ ] -+ } -+ ``` -+ -+ Then all the containers will run the default hook `myhook` when start. -+ -+ currently it supports three hooks: "prestart", "poststart", "poststop". -+ See OCI spec definition for more information about "hooks". -+ - **--icc**=*true*|*false* - Allow unrestricted inter\-container and Docker daemon host communication. If - disabled, containers can still be linked together using the **--link** option -diff --git a/components/cli/vendor/github.com/docker/docker/api/types/types.go b/components/cli/vendor/github.com/docker/docker/api/types/types.go -index a8fae3ba32..2fb6c5478b 100644 ---- a/components/cli/vendor/github.com/docker/docker/api/types/types.go -+++ b/components/cli/vendor/github.com/docker/docker/api/types/types.go -@@ -192,6 +192,7 @@ type Info struct { - ServerVersion string - ClusterStore string - ClusterAdvertise string -+ HookSpec string - Runtimes map[string]Runtime - DefaultRuntime string - Swarm swarm.Info -diff --git a/components/engine/api/types/types.go b/components/engine/api/types/types.go -index 959e9eb447..820d513cbb 100644 ---- a/components/engine/api/types/types.go -+++ b/components/engine/api/types/types.go -@@ -194,6 +194,7 @@ type Info struct { - ServerVersion string - ClusterStore string - ClusterAdvertise string -+ HookSpec string - Runtimes map[string]Runtime - DefaultRuntime string - Swarm swarm.Info -diff --git a/components/engine/cmd/dockerd/config.go b/components/engine/cmd/dockerd/config.go -index 2c8ed8edb4..6f62b97da8 100644 ---- a/components/engine/cmd/dockerd/config.go -+++ b/components/engine/cmd/dockerd/config.go -@@ -56,6 +56,7 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) { - flags.StringVar(&conf.ClusterAdvertise, "cluster-advertise", "", "Address or interface name to advertise") - flags.StringVar(&conf.ClusterStore, "cluster-store", "", "URL of the distributed storage backend") - flags.Var(opts.NewNamedMapOpts("cluster-store-opts", conf.ClusterOpts, nil), "cluster-store-opt", "Set cluster store options") -+ flags.StringVar(&conf.HookSpec, "hook-spec", "", "Default hook spec file applied to all containers") - flags.StringVar(&conf.CorsHeaders, "api-cors-header", "", "Set CORS headers in the Engine API") - flags.IntVar(&maxConcurrentDownloads, "max-concurrent-downloads", config.DefaultMaxConcurrentDownloads, "Set the max concurrent downloads for each pull") - flags.IntVar(&maxConcurrentUploads, "max-concurrent-uploads", config.DefaultMaxConcurrentUploads, "Set the max concurrent uploads for each push") -diff --git a/components/engine/daemon/config/config.go b/components/engine/daemon/config/config.go -index 8b2c844a57..2141ce8c54 100644 ---- a/components/engine/daemon/config/config.go -+++ b/components/engine/daemon/config/config.go -@@ -124,6 +124,7 @@ type CommonConfig struct { - ExecOptions []string `json:"exec-opts,omitempty"` - GraphDriver string `json:"storage-driver,omitempty"` - GraphOptions []string `json:"storage-opts,omitempty"` -+ HookSpec string `json:"hook-spec,omitempty"` - Labels []string `json:"labels,omitempty"` - Mtu int `json:"mtu,omitempty"` - NetworkDiagnosticPort int `json:"network-diagnostic-port,omitempty"` -diff --git a/components/engine/daemon/container.go b/components/engine/daemon/container.go -index 0864443513..8f9f6baf25 100644 ---- a/components/engine/daemon/container.go -+++ b/components/engine/daemon/container.go -@@ -13,16 +13,19 @@ import ( - containertypes "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/strslice" - "github.com/docker/docker/container" -+ "github.com/docker/docker/daemon/config" - "github.com/docker/docker/daemon/network" - "github.com/docker/docker/errdefs" - "github.com/docker/docker/image" - "github.com/docker/docker/opts" -+ "github.com/docker/docker/pkg/idtools" - "github.com/docker/docker/pkg/signal" - "github.com/docker/docker/pkg/system" - "github.com/docker/docker/pkg/truncindex" - "github.com/docker/docker/runconfig" - volumemounts "github.com/docker/docker/volume/mounts" - "github.com/docker/go-connections/nat" -+ "github.com/opencontainers/runtime-spec/specs-go" - "github.com/opencontainers/selinux/go-selinux/label" - "github.com/pkg/errors" - ) -@@ -226,7 +229,7 @@ func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig * - } - - // register hooks to container -- if err := daemon.registerHooks(container, hostConfig); err != nil { -+ if err := daemon.registerHooks(container, hostConfig.HookSpec); err != nil { - return err - } - -@@ -235,41 +238,112 @@ func (daemon *Daemon) setHostConfig(container *container.Container, hostConfig * - return container.CheckpointTo(daemon.containersReplica) - } - -+func (daemon *Daemon) sanitizeHookSpec(spec string) (string, error) { -+ if spec != "" { -+ spec = filepath.Clean(spec) -+ if !filepath.IsAbs(spec) { -+ return "", fmt.Errorf("hook spec file must be an absolute path") -+ } -+ fi, err := os.Stat(spec) -+ if err != nil { -+ return "", fmt.Errorf("stat hook spec file failed: %v", err) -+ } -+ if !fi.Mode().IsRegular() { -+ return "", fmt.Errorf("hook spec file must be a regular text file") -+ } -+ } -+ return spec, nil -+} -+ -+func (daemon *Daemon) initHooks(config *config.Config, rootIdentity idtools.Identity) error { -+ // create hook store dir -+ var err error -+ hookDir := filepath.Join(config.Root, "hooks") -+ if err = idtools.MkdirAllAndChown(hookDir, 0700, rootIdentity); err != nil && !os.IsExist(err) { -+ return err -+ } -+ daemon.hookStore = hookDir -+ -+ if config.HookSpec, err = daemon.sanitizeHookSpec(config.HookSpec); err != nil { -+ return err -+ } -+ -+ // setup default hooks -+ if err := daemon.registerDaemonHooks(config.HookSpec); err != nil { -+ return err -+ } -+ -+ return nil -+} - --func (daemon *Daemon) registerHooks(container *container.Container, hostConfig *containertypes.HostConfig) error { -- if hostConfig.HookSpec == "" { -+func (daemon *Daemon) registerDaemonHooks(hookspec string) error { -+ if hookspec == "" { - return nil - } -+ - // the hook spec has already been sanitized, so no need for validation again -- f, err := os.Open(hostConfig.HookSpec) -+ f, err := os.Open(hookspec) - if err != nil { - return fmt.Errorf("open hook spec file error: %v", err) - } - defer f.Close() - -- if err = json.NewDecoder(f).Decode(&container.Hooks); err != nil { -+ if err = json.NewDecoder(f).Decode(&daemon.Hooks); err != nil { - return fmt.Errorf("malformed hook spec, is your spec file in json format? error: %v", err) - } - - // hook path must be absolute and must be subdir of XXX -- if err = daemon.validateHook(container); err != nil { -+ if err = daemon.validateHook(&daemon.Hooks); err != nil { - return err - } -+ -+ return nil -+} -+ -+func (daemon *Daemon) registerHooks(container *container.Container, hookspec string) error { -+ container.Hooks.Prestart = append(container.Hooks.Prestart, daemon.Hooks.Prestart...) -+ container.Hooks.Poststart = append(container.Hooks.Poststart, daemon.Hooks.Poststart...) -+ container.Hooks.Poststop = append(container.Hooks.Poststop, daemon.Hooks.Poststop...) -+ if hookspec == "" { -+ return nil -+ } -+ -+ // the hook spec has already been sanitized, so no need for validation again -+ f, err := os.Open(hookspec) -+ if err != nil { -+ return fmt.Errorf("open hook spec file error: %v", err) -+ } -+ defer f.Close() -+ -+ var hooks specs.Hooks -+ if err = json.NewDecoder(f).Decode(&hooks); err != nil { -+ return fmt.Errorf("malformed hook spec, is your spec file in json format? error: %v", err) -+ } -+ -+ container.Hooks.Prestart = append(container.Hooks.Prestart, hooks.Prestart...) -+ container.Hooks.Poststart = append(container.Hooks.Poststart, hooks.Poststart...) -+ container.Hooks.Poststop = append(container.Hooks.Poststop, hooks.Poststop...) -+ -+ // hook path must be absolute and must be subdir of XXX -+ if err = daemon.validateHook(&container.Hooks); err != nil { -+ return err -+ } -+ - return nil - } - --func (daemon *Daemon) validateHook(container *container.Container) error { -- for _, v := range container.Hooks.Prestart { -+func (daemon *Daemon) validateHook(hooks *specs.Hooks) error { -+ for _, v := range hooks.Prestart { - if err := daemon.validateHookPath(v.Path); err != nil { - return err - } - } -- for _, v := range container.Hooks.Poststart { -+ for _, v := range hooks.Poststart { - if err := daemon.validateHookPath(v.Path); err != nil { - return err - } - } -- for _, v := range container.Hooks.Poststop { -+ for _, v := range hooks.Poststop { - if err := daemon.validateHookPath(v.Path); err != nil { - return err - } -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index d1f3131c4f..f7635f27cc 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -67,6 +67,7 @@ import ( - "github.com/docker/libnetwork" - "github.com/docker/libnetwork/cluster" - nwconfig "github.com/docker/libnetwork/config" -+ "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" - ) - -@@ -109,6 +110,7 @@ type Daemon struct { - containerdCli *containerd.Client - containerd libcontainerd.Client - defaultIsolation containertypes.Isolation // Default isolation mode on Windows -+ Hooks specs.Hooks - clusterProvider cluster.Provider - cluster Cluster - genericResources []swarm.GenericResource -@@ -997,6 +999,11 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S - return nil, errors.New("Devices cgroup isn't mounted") - } - -+ // setup hooks environment -+ if err := d.initHooks(config, rootIDs); err != nil { -+ return nil, fmt.Errorf("Failed to register default hooks: %v", err) -+ } -+ - d.ID = trustKey.PublicKey().KeyID() - d.repository = daemonRepo - d.containers = container.NewMemoryStore() -diff --git a/components/engine/daemon/info.go b/components/engine/daemon/info.go -index 262719d9d1..523a396643 100644 ---- a/components/engine/daemon/info.go -+++ b/components/engine/daemon/info.go -@@ -67,6 +67,7 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) { - HTTPSProxy: maskCredentials(sockets.GetProxyEnv("https_proxy")), - NoProxy: sockets.GetProxyEnv("no_proxy"), - LiveRestoreEnabled: daemon.configStore.LiveRestoreEnabled, -+ HookSpec: daemon.configStore.HookSpec, - Isolation: daemon.defaultIsolation, - } - --- -2.17.1 - diff --git a/patch/0015-hookspec-add-limit-of-hook-spec-file.patch b/patch/0015-hookspec-add-limit-of-hook-spec-file.patch deleted file mode 100644 index 9fce5b7..0000000 --- a/patch/0015-hookspec-add-limit-of-hook-spec-file.patch +++ /dev/null @@ -1,72 +0,0 @@ -From a6c5e3824b6b8d3a443e1a14136360cc73779296 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:17:06 +0800 -Subject: [PATCH 015/111] hookspec: add limit of hook spec file - -reason: add limit of hook spec file, to prevent docker daemon OOM. - -Change-Id: I11afebf163de3c401ed4f9b8f30c403f1d15de77 -Signed-off-by: xiadanni -Signed-off-by: lujingxiao ---- - components/engine/daemon/container.go | 8 ++++++++ - components/engine/daemon/daemon_unix.go | 15 ++------------- - 2 files changed, 10 insertions(+), 13 deletions(-) - -diff --git a/components/engine/daemon/container.go b/components/engine/daemon/container.go -index 8f9f6baf25..a8cb950f44 100644 ---- a/components/engine/daemon/container.go -+++ b/components/engine/daemon/container.go -@@ -30,6 +30,11 @@ import ( - "github.com/pkg/errors" - ) - -+const ( -+ // hook spec file size limit (in bytes) -+ hookSpecSizeLimit = (10 * 1024 * 1024) -+) -+ - // GetContainer looks for a container using the provided information, which could be - // one of the following inputs from the caller: - // - A full container ID, which will exact match a container in daemon's list -@@ -251,6 +256,9 @@ func (daemon *Daemon) sanitizeHookSpec(spec string) (string, error) { - if !fi.Mode().IsRegular() { - return "", fmt.Errorf("hook spec file must be a regular text file") - } -+ if fi.Size() > hookSpecSizeLimit { -+ return "", fmt.Errorf("Hook spec file size must not exceed %d bytes", hookSpecSizeLimit) -+ } - } - return spec, nil - } -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index ebf4e067fb..5b390d2db1 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -628,21 +628,10 @@ func (daemon *Daemon) verifyPlatformContainerSettings(hostConfig *containertypes - } - } - -- if hostConfig.HookSpec != "" { -- hostConfig.HookSpec = filepath.Clean(hostConfig.HookSpec) -- if !filepath.IsAbs(hostConfig.HookSpec) { -- return warnings, fmt.Errorf("Hook spec file must be an absolute path") -- } -- fi, err := os.Stat(hostConfig.HookSpec) -- if err != nil { -- return warnings, fmt.Errorf("stat hook spec file failed: %v", err) -- } -- if !fi.Mode().IsRegular() { -- return warnings, fmt.Errorf("Hook spec file must be a regular text file") -- } -+ if hostConfig.HookSpec, err = daemon.sanitizeHookSpec(hostConfig.HookSpec); err != nil { -+ return warnings, err - } - -- - if hostConfig.Runtime == "" { - hostConfig.Runtime = daemon.configStore.GetDefaultRuntimeName() - } --- -2.17.1 - diff --git a/patch/0016-hookspec-fix-hooks-nil-pointer-dereference.patch b/patch/0016-hookspec-fix-hooks-nil-pointer-dereference.patch deleted file mode 100644 index b406e09..0000000 --- a/patch/0016-hookspec-fix-hooks-nil-pointer-dereference.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 8dd367f460008bbe1715117610b1eb48cb5b20bf Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:17:23 +0800 -Subject: [PATCH 016/111] hookspec: fix hooks nil pointer dereference - -reason: merge containerd and runc into one version for docker-1.11.2 and -docker-17.06 - -Change-Id: I1b0899cf18f2734bb205026b3094f1a3264a695e -Signed-off-by: jingrui -Signed-off-by: xiadanni -Signed-off-by: lujingxiao ---- - components/engine/oci/defaults.go | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/components/engine/oci/defaults.go b/components/engine/oci/defaults.go -index 992157b0f5..5e17ea3f38 100644 ---- a/components/engine/oci/defaults.go -+++ b/components/engine/oci/defaults.go -@@ -66,6 +66,7 @@ func DefaultLinuxSpec() specs.Spec { - }, - }, - Root: &specs.Root{}, -+ Hooks: &specs.Hooks{}, - } - s.Mounts = []specs.Mount{ - { --- -2.17.1 - diff --git a/patch/0017-hookspec-canonicalize-hook-path-before-valida.patch b/patch/0017-hookspec-canonicalize-hook-path-before-valida.patch deleted file mode 100644 index 85c5191..0000000 --- a/patch/0017-hookspec-canonicalize-hook-path-before-valida.patch +++ /dev/null @@ -1,45 +0,0 @@ -From fe67259fd158b8193db31fad83f2dc3d3d3bc5c4 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:17:38 +0800 -Subject: [PATCH 017/111] hookspec: canonicalize hook path before - validation - -reason:hook programs must put under hook directory, but if we refer - them with a symbolic link path in hookspecs, docker daemon refuse - to run. so we just canonicalize path first before check. - -Change-Id: I68d3757f26d7df05eb048e686368eca061cb06a9 -Signed-off-by: zhangyuyun -Signed-off-by: xiadanni -Signed-off-by: lujingxiao ---- - components/engine/daemon/container.go | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/components/engine/daemon/container.go b/components/engine/daemon/container.go -index a8cb950f44..06a19bb4c8 100644 ---- a/components/engine/daemon/container.go -+++ b/components/engine/daemon/container.go -@@ -366,8 +366,17 @@ func (daemon *Daemon) validateHookPath(path string) error { - return fmt.Errorf("Hook path %q must be an absolute path", path) - } - -- if !filepath.HasPrefix(path, daemon.hookStore) { -- return fmt.Errorf("hook program must be put under %q", daemon.hookStore) -+ realPath, err := filepath.EvalSymlinks(path) -+ if err != nil { -+ if !strings.Contains(err.Error(), "no such file or directory") { -+ return fmt.Errorf("failed to canonicalise path for %s: %s", path, err) -+ } -+ // for backward compatibility -+ realPath = path -+ } -+ -+ if !filepath.HasPrefix(realPath, daemon.hookStore) { -+ return fmt.Errorf("hook path %q isn't right, hook program must be put under %q", path, daemon.hookStore) - } - return nil - } --- -2.17.1 - diff --git a/patch/0018-dfx-trylock-add-trylock-and-trylocktimeout-fo.patch b/patch/0018-dfx-trylock-add-trylock-and-trylocktimeout-fo.patch deleted file mode 100644 index b2137f0..0000000 --- a/patch/0018-dfx-trylock-add-trylock-and-trylocktimeout-fo.patch +++ /dev/null @@ -1,362 +0,0 @@ -From 6a9e68763da72ebc0b9a7e45cd08ce57fe11998f Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:21:56 +0800 -Subject: [PATCH 018/111] dfx/trylock: add trylock and trylocktimeout - for docker inspect - -reason:In order to avoid deadlocks, add trylock and trylocktimeout - for docker inspect commmand. The -t/--time is a parameter of - docker inspect command, set by user, and the default value - is 120s. - -Change-Id: Ie30ff28941624cc595e2a30d453d6f90b265d803 -Signed-off-by: zhangyu235 -Signed-off-by: lujingxiao ---- - .../cli/cli/command/container/inspect.go | 4 +- - components/cli/cli/command/system/inspect.go | 12 ++-- - .../github.com/docker/docker/client/Checklist | 1 + - .../docker/docker/client/container_inspect.go | 4 +- - .../docker/docker/client/interface.go | 2 +- - .../api/server/router/container/backend.go | 2 +- - .../api/server/router/container/inspect.go | 4 +- - components/engine/container/state.go | 4 +- - .../engine/daemon/cluster/executor/backend.go | 2 +- - .../cluster/executor/container/adapter.go | 3 +- - components/engine/daemon/inspect.go | 12 ++-- - components/engine/pkg/trylock/mutex.go | 61 +++++++++++++++++++ - 12 files changed, 93 insertions(+), 18 deletions(-) - create mode 100644 components/cli/vendor/github.com/docker/docker/client/Checklist - create mode 100644 components/engine/pkg/trylock/mutex.go - -diff --git a/components/cli/cli/command/container/inspect.go b/components/cli/cli/command/container/inspect.go -index 4f50e2a080..b77994e896 100644 ---- a/components/cli/cli/command/container/inspect.go -+++ b/components/cli/cli/command/container/inspect.go -@@ -13,6 +13,7 @@ type inspectOptions struct { - format string - size bool - refs []string -+ time int - } - - // newInspectCommand creates a new cobra.Command for `docker container inspect` -@@ -32,6 +33,7 @@ func newInspectCommand(dockerCli command.Cli) *cobra.Command { - flags := cmd.Flags() - flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given Go template") - flags.BoolVarP(&opts.size, "size", "s", false, "Display total file sizes") -+ flags.IntVarP(&opts.time, "time", "t", 120, "Seconds to wait for inspect timeout") - - return cmd - } -@@ -41,7 +43,7 @@ func runInspect(dockerCli command.Cli, opts inspectOptions) error { - ctx := context.Background() - - getRefFunc := func(ref string) (interface{}, []byte, error) { -- return client.ContainerInspectWithRaw(ctx, ref, opts.size) -+ return client.ContainerInspectWithRaw(ctx, ref, opts.size, opts.time) - } - return inspect.Inspect(dockerCli.Out(), opts.refs, opts.format, getRefFunc) - } -diff --git a/components/cli/cli/command/system/inspect.go b/components/cli/cli/command/system/inspect.go -index b49b4b33d3..248f9caad2 100644 ---- a/components/cli/cli/command/system/inspect.go -+++ b/components/cli/cli/command/system/inspect.go -@@ -19,6 +19,7 @@ type inspectOptions struct { - inspectType string - size bool - ids []string -+ time int - } - - // NewInspectCommand creates a new cobra.Command for `docker inspect` -@@ -39,6 +40,7 @@ func NewInspectCommand(dockerCli command.Cli) *cobra.Command { - flags.StringVarP(&opts.format, "format", "f", "", "Format the output using the given Go template") - flags.StringVar(&opts.inspectType, "type", "", "Return JSON for specified type") - flags.BoolVarP(&opts.size, "size", "s", false, "Display total file sizes if the type is container") -+ flags.IntVarP(&opts.time, "time", "t", 120, "Seconds to wait for inspect timeout") - - return cmd - } -@@ -47,16 +49,16 @@ func runInspect(dockerCli command.Cli, opts inspectOptions) error { - var elementSearcher inspect.GetRefFunc - switch opts.inspectType { - case "", "container", "image", "node", "network", "service", "volume", "task", "plugin", "secret": -- elementSearcher = inspectAll(context.Background(), dockerCli, opts.size, opts.inspectType) -+ elementSearcher = inspectAll(context.Background(), dockerCli, opts.size, opts.inspectType, opts.time) - default: - return errors.Errorf("%q is not a valid value for --type", opts.inspectType) - } - return inspect.Inspect(dockerCli.Out(), opts.ids, opts.format, elementSearcher) - } - --func inspectContainers(ctx context.Context, dockerCli command.Cli, getSize bool) inspect.GetRefFunc { -+func inspectContainers(ctx context.Context, dockerCli command.Cli, getSize bool, timeout int) inspect.GetRefFunc { - return func(ref string) (interface{}, []byte, error) { -- return dockerCli.Client().ContainerInspectWithRaw(ctx, ref, getSize) -+ return dockerCli.Client().ContainerInspectWithRaw(ctx, ref, getSize, timeout) - } - } - -@@ -109,7 +111,7 @@ func inspectSecret(ctx context.Context, dockerCli command.Cli) inspect.GetRefFun - } - } - --func inspectAll(ctx context.Context, dockerCli command.Cli, getSize bool, typeConstraint string) inspect.GetRefFunc { -+func inspectAll(ctx context.Context, dockerCli command.Cli, getSize bool, typeConstraint string, timeout int) inspect.GetRefFunc { - var inspectAutodetect = []struct { - objectType string - isSizeSupported bool -@@ -119,7 +121,7 @@ func inspectAll(ctx context.Context, dockerCli command.Cli, getSize bool, typeCo - { - objectType: "container", - isSizeSupported: true, -- objectInspector: inspectContainers(ctx, dockerCli, getSize), -+ objectInspector: inspectContainers(ctx, dockerCli, getSize, timeout), - }, - { - objectType: "image", -diff --git a/components/cli/vendor/github.com/docker/docker/client/Checklist b/components/cli/vendor/github.com/docker/docker/client/Checklist -new file mode 100644 -index 0000000000..9b1682dc41 ---- /dev/null -+++ b/components/cli/vendor/github.com/docker/docker/client/Checklist -@@ -0,0 +1 @@ -+Add trylcok and trylocktimeout for docker inspect commmand. -diff --git a/components/cli/vendor/github.com/docker/docker/client/container_inspect.go b/components/cli/vendor/github.com/docker/docker/client/container_inspect.go -index f453064cf8..b8573fd40b 100644 ---- a/components/cli/vendor/github.com/docker/docker/client/container_inspect.go -+++ b/components/cli/vendor/github.com/docker/docker/client/container_inspect.go -@@ -6,6 +6,7 @@ import ( - "encoding/json" - "io/ioutil" - "net/url" -+ "strconv" - - "github.com/docker/docker/api/types" - ) -@@ -27,7 +28,7 @@ func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (ty - } - - // ContainerInspectWithRaw returns the container information and its raw representation. --func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (types.ContainerJSON, []byte, error) { -+func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool, timeout int) (types.ContainerJSON, []byte, error) { - if containerID == "" { - return types.ContainerJSON{}, nil, objectNotFoundError{object: "container", id: containerID} - } -@@ -35,6 +36,7 @@ func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID stri - if getSize { - query.Set("size", "1") - } -+ query.Set("t", strconv.Itoa(timeout)) - serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil) - if err != nil { - return types.ContainerJSON{}, nil, wrapResponseError(err, serverResp, "container", containerID) -diff --git a/components/cli/vendor/github.com/docker/docker/client/interface.go b/components/cli/vendor/github.com/docker/docker/client/interface.go -index d190f8e58d..b2d5d7bb72 100644 ---- a/components/cli/vendor/github.com/docker/docker/client/interface.go -+++ b/components/cli/vendor/github.com/docker/docker/client/interface.go -@@ -56,7 +56,7 @@ type ContainerAPIClient interface { - ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error - ContainerExport(ctx context.Context, container string) (io.ReadCloser, error) - ContainerInspect(ctx context.Context, container string) (types.ContainerJSON, error) -- ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (types.ContainerJSON, []byte, error) -+ ContainerInspectWithRaw(ctx context.Context, container string, getSize bool, timeout int) (types.ContainerJSON, []byte, error) - ContainerKill(ctx context.Context, container, signal string) error - ContainerList(ctx context.Context, options types.ContainerListOptions) ([]types.Container, error) - ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error) -diff --git a/components/engine/api/server/router/container/backend.go b/components/engine/api/server/router/container/backend.go -index 75ea1d82b7..88fbe71a88 100644 ---- a/components/engine/api/server/router/container/backend.go -+++ b/components/engine/api/server/router/container/backend.go -@@ -49,7 +49,7 @@ type stateBackend interface { - // monitorBackend includes functions to implement to provide containers monitoring functionality. - type monitorBackend interface { - ContainerChanges(name string) ([]archive.Change, error) -- ContainerInspect(name string, size bool, version string) (interface{}, error) -+ ContainerInspect(name string, size bool, version string, timeout int) (interface{}, error) - ContainerLogs(ctx context.Context, name string, config *types.ContainerLogsOptions) (msgs <-chan *backend.LogMessage, tty bool, err error) - ContainerStats(ctx context.Context, name string, config *backend.ContainerStatsConfig) error - ContainerTop(name string, psArgs string) (*container.ContainerTopOKBody, error) -diff --git a/components/engine/api/server/router/container/inspect.go b/components/engine/api/server/router/container/inspect.go -index 5c78d15bc9..cb6eb50251 100644 ---- a/components/engine/api/server/router/container/inspect.go -+++ b/components/engine/api/server/router/container/inspect.go -@@ -3,6 +3,7 @@ package container // import "github.com/docker/docker/api/server/router/containe - import ( - "context" - "net/http" -+ "strconv" - - "github.com/docker/docker/api/server/httputils" - ) -@@ -12,7 +13,8 @@ func (s *containerRouter) getContainersByName(ctx context.Context, w http.Respon - displaySize := httputils.BoolValue(r, "size") - - version := httputils.VersionFromContext(ctx) -- json, err := s.backend.ContainerInspect(vars["name"], displaySize, version) -+ timeout, _ := strconv.Atoi(r.Form.Get("t")) -+ json, err := s.backend.ContainerInspect(vars["name"], displaySize, version, timeout) - if err != nil { - return err - } -diff --git a/components/engine/container/state.go b/components/engine/container/state.go -index 7c2a1ec81c..91ea30a76e 100644 ---- a/components/engine/container/state.go -+++ b/components/engine/container/state.go -@@ -4,10 +4,10 @@ import ( - "context" - "errors" - "fmt" -- "sync" - "time" - - "github.com/docker/docker/api/types" -+ "github.com/docker/docker/pkg/trylock" - "github.com/docker/go-units" - ) - -@@ -15,7 +15,7 @@ import ( - // set the state. Container has an embed, which allows all of the - // functions defined against State to run against Container. - type State struct { -- sync.Mutex -+ trylock.TryMutex - // Note that `Running` and `Paused` are not mutually exclusive: - // When pausing a container (on Linux), the cgroups freezer is used to suspend - // all processes in the container. Freezing the process requires the process to -diff --git a/components/engine/daemon/cluster/executor/backend.go b/components/engine/daemon/cluster/executor/backend.go -index cfbc86ce36..c9ff4503bc 100644 ---- a/components/engine/daemon/cluster/executor/backend.go -+++ b/components/engine/daemon/cluster/executor/backend.go -@@ -41,7 +41,7 @@ type Backend interface { - ActivateContainerServiceBinding(containerName string) error - DeactivateContainerServiceBinding(containerName string) error - UpdateContainerServiceConfig(containerName string, serviceConfig *clustertypes.ServiceConfig) error -- ContainerInspectCurrent(name string, size bool) (*types.ContainerJSON, error) -+ ContainerInspectCurrent(name string, size bool, timeout int) (*types.ContainerJSON, error) - ContainerWait(ctx context.Context, name string, condition containerpkg.WaitCondition) (<-chan containerpkg.StateStatus, error) - ContainerRm(name string, config *types.ContainerRmConfig) error - ContainerKill(name string, sig uint64) error -diff --git a/components/engine/daemon/cluster/executor/container/adapter.go b/components/engine/daemon/cluster/executor/container/adapter.go -index 720b8447fc..3743cb6418 100644 ---- a/components/engine/daemon/cluster/executor/container/adapter.go -+++ b/components/engine/daemon/cluster/executor/container/adapter.go -@@ -351,7 +351,8 @@ func (c *containerAdapter) start(ctx context.Context) error { - } - - func (c *containerAdapter) inspect(ctx context.Context) (types.ContainerJSON, error) { -- cs, err := c.backend.ContainerInspectCurrent(c.container.name(), false) -+ timeout := -1 -+ cs, err := c.backend.ContainerInspectCurrent(c.container.name(), false, timeout) - if ctx.Err() != nil { - return types.ContainerJSON{}, ctx.Err() - } -diff --git a/components/engine/daemon/inspect.go b/components/engine/daemon/inspect.go -index 45a2154254..be8f6eff71 100644 ---- a/components/engine/daemon/inspect.go -+++ b/components/engine/daemon/inspect.go -@@ -19,25 +19,29 @@ import ( - // ContainerInspect returns low-level information about a - // container. Returns an error if the container cannot be found, or if - // there is an error getting the data. --func (daemon *Daemon) ContainerInspect(name string, size bool, version string) (interface{}, error) { -+func (daemon *Daemon) ContainerInspect(name string, size bool, version string, timeout int) (interface{}, error) { - switch { - case versions.LessThan(version, "1.20"): - return daemon.containerInspectPre120(name) - case versions.Equal(version, "1.20"): - return daemon.containerInspect120(name) - } -- return daemon.ContainerInspectCurrent(name, size) -+ return daemon.ContainerInspectCurrent(name, size, timeout) - } - - // ContainerInspectCurrent returns low-level information about a - // container in a most recent api version. --func (daemon *Daemon) ContainerInspectCurrent(name string, size bool) (*types.ContainerJSON, error) { -+func (daemon *Daemon) ContainerInspectCurrent(name string, size bool, timeout int) (*types.ContainerJSON, error) { - container, err := daemon.GetContainer(name) - if err != nil { - return nil, err - } - -- container.Lock() -+ // The unit of timeout is seconds, and the unit of frequency is milliseconds. -+ lockTimeoutSuccess := container.TryLockTimeout(timeout, 100) -+ if lockTimeoutSuccess == false { -+ return nil, fmt.Errorf("Container %s inspect failed due to trylock timeout for %ds.", name, timeout) -+ } - - base, err := daemon.getInspectData(container) - if err != nil { -diff --git a/components/engine/pkg/trylock/mutex.go b/components/engine/pkg/trylock/mutex.go -new file mode 100644 -index 0000000000..18b3c3cca7 ---- /dev/null -+++ b/components/engine/pkg/trylock/mutex.go -@@ -0,0 +1,61 @@ -+package trylock -+ -+import ( -+ "sync" -+ "sync/atomic" -+ "time" -+ "unsafe" -+) -+ -+const mutexLocked = 1 << iota -+ -+// Mutex is simple sync.Mutex + ability to try to Lock. -+type TryMutex struct { -+ in sync.Mutex -+} -+ -+// Lock locks m. -+// If the lock is already in use, the calling goroutine -+// blocks until the mutex is available. -+func (m *TryMutex) Lock() { -+ m.in.Lock() -+} -+ -+// Unlock unlocks m. -+// It is a run-time error if m is not locked on entry to Unlock. -+// -+// A locked Mutex is not associated with a particular goroutine. -+// It is allowed for one goroutine to lock a Mutex and then -+// arrange for another goroutine to unlock it. -+func (m *TryMutex) Unlock() { -+ m.in.Unlock() -+} -+ -+// TryLock tries to lock m. It returns true in case of success, false otherwise. -+func (m *TryMutex) TryLock() bool { -+ return atomic.CompareAndSwapInt32((*int32)(unsafe.Pointer(&m.in)), 0, mutexLocked) -+} -+ -+// TryLockTimeout tries to lock m at a certain frequency for a certain period of time. -+// It returns true in case of success, false otherwise. -+func (m *TryMutex) TryLockTimeout(timeout int, frequency int) bool { -+ if timeout <= 0 { -+ m.Lock() -+ return true -+ } else { -+ timer := time.After(time.Second * time.Duration(timeout)) -+ result := false -+ for { -+ select { -+ case <-timer: -+ return result -+ default: -+ } -+ result = atomic.CompareAndSwapInt32((*int32)(unsafe.Pointer(&m.in)), 0, mutexLocked) -+ if result { -+ return result -+ } -+ time.Sleep(time.Millisecond * time.Duration(frequency)) -+ } -+ } -+} --- -2.17.1 - diff --git a/patch/0019-dfx-print-container-name-and-id-when-create-d.patch b/patch/0019-dfx-print-container-name-and-id-when-create-d.patch deleted file mode 100644 index c7fbdb4..0000000 --- a/patch/0019-dfx-print-container-name-and-id-when-create-d.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 9e05ad46f060ab47559cd1566a95ec579fbc08ac Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:18:35 +0800 -Subject: [PATCH 019/111] dfx: print container name and id when create - done - -reason:print container name and id when create done - -Change-Id: I62932133c2a28e24adb54a40d16e2792a0772185 -Signed-off-by: dengguangxing -Signed-off-by: zhangsong34 -Signed-off-by: lujingxiao ---- - components/engine/daemon/create.go | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/components/engine/daemon/create.go b/components/engine/daemon/create.go -index 1afb1bebea..565e9dc022 100644 ---- a/components/engine/daemon/create.go -+++ b/components/engine/daemon/create.go -@@ -74,6 +74,7 @@ func (daemon *Daemon) containerCreate(params types.ContainerCreateConfig, manage - return containertypes.ContainerCreateCreatedBody{Warnings: warnings}, err - } - containerActions.WithValues("create").UpdateSince(start) -+ logrus.Infof("Container create done(Name: %s ID: %s)", container.Name, container.ID) - - return containertypes.ContainerCreateCreatedBody{ID: container.ID, Warnings: warnings}, nil - } --- -2.17.1 - diff --git a/patch/0020-cleanup-remove-redundant-files-in-graphdriver.patch b/patch/0020-cleanup-remove-redundant-files-in-graphdriver.patch deleted file mode 100644 index e2e3a4d..0000000 --- a/patch/0020-cleanup-remove-redundant-files-in-graphdriver.patch +++ /dev/null @@ -1,441 +0,0 @@ -From b555ed1bb121b0740665fb0db9f7fea3b339f98c Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:22:22 +0800 -Subject: [PATCH 020/111] cleanup: remove redundant files in - graphdriver and mount dir - -reason:remove redundant files in graphdriver and mount dir - -Change-Id: Ie75b78ac1e288d2c909dcd446636d16b1dd60363 -Signed-off-by: yangshukui -Signed-off-by: zhangsong34 -Signed-off-by: lujingxiao ---- - components/engine/daemon/daemon.go | 28 ++++++- - .../engine/daemon/graphdriver/aufs/aufs.go | 5 ++ - .../engine/daemon/graphdriver/btrfs/btrfs.go | 5 ++ - .../daemon/graphdriver/devmapper/driver.go | 5 ++ - .../engine/daemon/graphdriver/driver.go | 2 + - .../daemon/graphdriver/overlay/overlay.go | 5 ++ - .../daemon/graphdriver/overlay2/overlay.go | 19 +++++ - components/engine/daemon/graphdriver/proxy.go | 5 ++ - .../engine/daemon/graphdriver/vfs/driver.go | 5 ++ - .../engine/daemon/graphdriver/zfs/zfs.go | 5 ++ - components/engine/daemon/images/service.go | 4 + - .../engine/distribution/xfer/download_test.go | 4 + - components/engine/layer/layer.go | 1 + - components/engine/layer/layer_store.go | 73 +++++++++++++++++++ - components/engine/pkg/ioutils/fswriters.go | 36 +++++++++ - components/engine/reference/store.go | 1 + - 16 files changed, 201 insertions(+), 2 deletions(-) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index f7635f27cc..4546587369 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -262,7 +262,15 @@ func (daemon *Daemon) restore() error { - id := v.Name() - container, err := daemon.load(id) - if err != nil { -- logrus.Errorf("Failed to load container %v: %v", id, err) -+ logrus.Errorf("Failed to load container %v: %v. Try to remove it", id, err) -+ cdir := filepath.Join(daemon.repository, id) -+ // to make sure we are not in fd exhausted state -+ if !strings.Contains(err.Error(), "too many open files") { -+ logrus.Warnf("remove invalid container data: %s", cdir) -+ if err := system.EnsureRemoveAll(cdir); err != nil { -+ logrus.Warnf("remove %s error: %v", cdir, err) -+ } -+ } - continue - } - if !system.IsOSSupported(container.OS) { -@@ -274,7 +282,12 @@ func (daemon *Daemon) restore() error { - if (container.Driver == "" && currentDriverForContainerOS == "aufs") || container.Driver == currentDriverForContainerOS { - rwlayer, err := daemon.imageService.GetLayerByID(container.ID, container.OS) - if err != nil { -- logrus.Errorf("Failed to load container mount %v: %v", id, err) -+ logrus.Errorf("Failed to load container mount %v: %v. Try to remove it", id, err) -+ cdir := filepath.Join(daemon.repository, id) -+ logrus.Warnf("remove invalid container data: %s", cdir) -+ if err := system.EnsureRemoveAll(cdir); err != nil { -+ logrus.Warnf("remove %s error: %v", cdir, err) -+ } - continue - } - container.RWLayer = rwlayer -@@ -472,6 +485,17 @@ func (daemon *Daemon) restore() error { - }(c) - } - wg.Wait() -+ -+ containerIDs := make(map[string]struct{}) -+ for cid, _ := range containers { -+ containerIDs[cid] = struct{}{} -+ } -+ -+ err = daemon.imageService.LayerStoreForOS(runtime.GOOS).CleanupRedundant(containerIDs) -+ if err != nil { -+ logrus.Errorf("cleanup redundant IDs in layerStore failed %s", err) -+ } -+ - daemon.netController, err = daemon.initNetworkController(daemon.configStore, activeSandboxes) - if err != nil { - return fmt.Errorf("Error initializing network controller: %v", err) -diff --git a/components/engine/daemon/graphdriver/aufs/aufs.go b/components/engine/daemon/graphdriver/aufs/aufs.go -index 114aa9a615..303138d48a 100644 ---- a/components/engine/daemon/graphdriver/aufs/aufs.go -+++ b/components/engine/daemon/graphdriver/aufs/aufs.go -@@ -230,6 +230,11 @@ func (a *Driver) Exists(id string) bool { - return true - } - -+// GetAll not implemented -+func (a *Driver) GetAll() []string { -+ return []string{} -+} -+ - // CreateReadWrite creates a layer that is writable for use as a container - // file system. - func (a *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error { -diff --git a/components/engine/daemon/graphdriver/btrfs/btrfs.go b/components/engine/daemon/graphdriver/btrfs/btrfs.go -index 7ce7edef36..d04ce10be9 100644 ---- a/components/engine/daemon/graphdriver/btrfs/btrfs.go -+++ b/components/engine/daemon/graphdriver/btrfs/btrfs.go -@@ -167,6 +167,11 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) { - return nil, nil - } - -+// GetAll not implemented -+func (a *Driver) GetAll() []string { -+ return []string{} -+} -+ - // Cleanup unmounts the home directory. - func (d *Driver) Cleanup() error { - err := d.subvolDisableQuota() -diff --git a/components/engine/daemon/graphdriver/devmapper/driver.go b/components/engine/daemon/graphdriver/devmapper/driver.go -index 623843f852..a56b26bc8f 100644 ---- a/components/engine/daemon/graphdriver/devmapper/driver.go -+++ b/components/engine/daemon/graphdriver/devmapper/driver.go -@@ -126,6 +126,11 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) { - return metadata, nil - } - -+// GetAll not implemented -+func (a *Driver) GetAll() []string { -+ return []string{} -+} -+ - // Cleanup unmounts a device. - func (d *Driver) Cleanup() error { - err := d.DeviceSet.Shutdown(d.home) -diff --git a/components/engine/daemon/graphdriver/driver.go b/components/engine/daemon/graphdriver/driver.go -index a9e1957393..672257a9b5 100644 ---- a/components/engine/daemon/graphdriver/driver.go -+++ b/components/engine/daemon/graphdriver/driver.go -@@ -78,6 +78,8 @@ type ProtoDriver interface { - // held by the driver, e.g., unmounting all layered filesystems - // known to this driver. - Cleanup() error -+ // GetAll returns all the mountid exists in this driver -+ GetAll() []string - } - - // DiffDriver is the interface to use to implement graph diffs -diff --git a/components/engine/daemon/graphdriver/overlay/overlay.go b/components/engine/daemon/graphdriver/overlay/overlay.go -index 08c05e192f..d59a6dfc83 100644 ---- a/components/engine/daemon/graphdriver/overlay/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay/overlay.go -@@ -264,6 +264,11 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) { - return metadata, nil - } - -+// GetAll not implemented -+func (a *Driver) GetAll() []string { -+ return []string{} -+} -+ - // Cleanup any state created by overlay which should be cleaned when daemon - // is being shutdown. For now, we just have to unmount the bind mounted - // we had created. -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index b969582eb3..7290616bae 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -507,6 +507,25 @@ func (d *Driver) dir(id string) string { - return path.Join(d.home, id) - } - -+func (d *Driver) GetAll() []string { -+ var ids []string -+ -+ fs, err := ioutil.ReadDir(d.home) -+ if err != nil { -+ logrus.Errorf("open directory(%s) failed: %s", d.home, err) -+ return ids -+ } -+ -+ for _, f := range fs { -+ if len(f.Name()) >= 64 { -+ ids = append(ids, f.Name()) -+ } -+ } -+ -+ return ids -+ -+} -+ - func (d *Driver) getLowerDirs(id string) ([]string, error) { - var lowersArray []string - lowers, err := ioutil.ReadFile(path.Join(d.dir(id), lowerFile)) -diff --git a/components/engine/daemon/graphdriver/proxy.go b/components/engine/daemon/graphdriver/proxy.go -index cb350d8074..6c132d40a8 100644 ---- a/components/engine/daemon/graphdriver/proxy.go -+++ b/components/engine/daemon/graphdriver/proxy.go -@@ -91,6 +91,11 @@ func (d *graphDriverProxy) Capabilities() Capabilities { - return d.caps - } - -+// GetAll not implemented -+func (d *graphDriverProxy) GetAll() []string { -+ return []string{} -+} -+ - func (d *graphDriverProxy) CreateReadWrite(id, parent string, opts *CreateOpts) error { - return d.create("GraphDriver.CreateReadWrite", id, parent, opts) - } -diff --git a/components/engine/daemon/graphdriver/vfs/driver.go b/components/engine/daemon/graphdriver/vfs/driver.go -index 33e6bf6cc9..8c2947d9ee 100644 ---- a/components/engine/daemon/graphdriver/vfs/driver.go -+++ b/components/engine/daemon/graphdriver/vfs/driver.go -@@ -64,6 +64,11 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) { - return nil, nil - } - -+// GetAll not implemented -+func (a *Driver) GetAll() []string { -+ return []string{} -+} -+ - // Cleanup is used to implement graphdriver.ProtoDriver. There is no cleanup required for this driver. - func (d *Driver) Cleanup() error { - return nil -diff --git a/components/engine/daemon/graphdriver/zfs/zfs.go b/components/engine/daemon/graphdriver/zfs/zfs.go -index 8a798778d2..e1e2d0d823 100644 ---- a/components/engine/daemon/graphdriver/zfs/zfs.go -+++ b/components/engine/daemon/graphdriver/zfs/zfs.go -@@ -227,6 +227,11 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) { - }, nil - } - -+// GetAll not implemented -+func (a *Driver) GetAll() []string { -+ return []string{} -+} -+ - func (d *Driver) cloneFilesystem(name, parentName string) error { - snapshotName := fmt.Sprintf("%d", time.Now().Nanosecond()) - parentDataset := zfs.Dataset{Name: parentName} -diff --git a/components/engine/daemon/images/service.go b/components/engine/daemon/images/service.go -index e8df5cb649..8d187e2603 100644 ---- a/components/engine/daemon/images/service.go -+++ b/components/engine/daemon/images/service.go -@@ -177,6 +177,10 @@ func (i *ImageService) GraphDriverForOS(os string) string { - return i.layerStores[os].DriverName() - } - -+func (i *ImageService) LayerStoreForOS(os string) layer.Store { -+ return i.layerStores[os] -+} -+ - // ReleaseLayer releases a layer allowing it to be removed - // called from delete.go Daemon.cleanupContainer(), and Daemon.containerExport() - func (i *ImageService) ReleaseLayer(rwlayer layer.RWLayer, containerOS string) error { -diff --git a/components/engine/distribution/xfer/download_test.go b/components/engine/distribution/xfer/download_test.go -index 4ab3705af6..91153591ed 100644 ---- a/components/engine/distribution/xfer/download_test.go -+++ b/components/engine/distribution/xfer/download_test.go -@@ -150,6 +150,10 @@ func (ls *mockLayerStore) DriverStatus() [][2]string { - return [][2]string{} - } - -+func (ls *mockLayerStore) CleanupRedundant(cids map[string]struct{}) error { -+ return nil -+} -+ - func (ls *mockLayerStore) DriverName() string { - return "mock" - } -diff --git a/components/engine/layer/layer.go b/components/engine/layer/layer.go -index d0c7fa8608..425006854d 100644 ---- a/components/engine/layer/layer.go -+++ b/components/engine/layer/layer.go -@@ -193,6 +193,7 @@ type Store interface { - Cleanup() error - DriverStatus() [][2]string - DriverName() string -+ CleanupRedundant(map[string]struct{}) error - } - - // DescribableStore represents a layer store capable of storing -diff --git a/components/engine/layer/layer_store.go b/components/engine/layer/layer_store.go -index bc3e8719fc..6a568e9d9b 100644 ---- a/components/engine/layer/layer_store.go -+++ b/components/engine/layer/layer_store.go -@@ -5,6 +5,7 @@ import ( - "fmt" - "io" - "io/ioutil" -+ "strings" - "sync" - - "github.com/docker/distribution" -@@ -460,6 +461,78 @@ func (ls *layerStore) releaseLayer(l *roLayer) ([]Metadata, error) { - } - } - -+// CleanupRedundant will cleanup useless dirs in image/mount and driver -+func (ls *layerStore) CleanupRedundant(cs map[string]struct{}) error { -+ cids, err := ls.getAndCleanCacheIDs(cs) -+ if err != nil { -+ return fmt.Errorf("get cacheIDs failed: %s", err) -+ } -+ -+ ids := ls.driver.GetAll() -+ -+ for _, id := range ids { -+ if _, ok := cids[id]; !ok { -+ logrus.Warnf("remove redundant cacheID: %s", id) -+ ls.driver.Remove(id) -+ } -+ } -+ return nil -+} -+ -+func (ls *layerStore) getAndCleanCacheIDs(cs map[string]struct{}) (map[string]struct{}, error) { -+ cids := make(map[string]struct{}) -+ -+ ids, mountids, err := ls.store.List() -+ if err != nil { -+ return cids, fmt.Errorf("failed to get mount list from store: %s", err) -+ } -+ -+ for _, id := range ids { -+ cid, err := ls.store.GetCacheID(id) -+ if err != nil { -+ logrus.Errorf("failed to get cache id for %s: %s", id, err) -+ // just return if we are not in fd exhausted state -+ if strings.Contains(err.Error(), "too many open files") { -+ return cids, err -+ } -+ continue -+ } -+ cids[cid] = struct{}{} -+ } -+ -+ for _, mid := range mountids { -+ // if mid not exist in current container list, just remove it -+ if _, ok := cs[mid]; !ok { -+ logrus.Warnf("remove redundant mountID: %s", mid) -+ ls.store.RemoveMount(mid) -+ continue -+ } -+ mountID, err := ls.store.GetMountID(mid) -+ if err != nil { -+ logrus.Errorf("failed to get mount id for %s: %s", mid, err) -+ // just return if we are not in fd exhausted state -+ if strings.Contains(err.Error(), "too many open files") { -+ return cids, err -+ } -+ } else { -+ cids[mountID] = struct{}{} -+ } -+ -+ initID, err := ls.store.GetInitID(mid) -+ if err != nil { -+ logrus.Errorf("failed to get init id for %s: %s", mid, err) -+ // just return if we are not in fd exhausted state -+ if strings.Contains(err.Error(), "too many open files") { -+ return cids, err -+ } -+ continue -+ } -+ cids[initID] = struct{}{} -+ } -+ -+ return cids, nil -+} -+ - func (ls *layerStore) Release(l Layer) ([]Metadata, error) { - ls.layerL.Lock() - defer ls.layerL.Unlock() -diff --git a/components/engine/pkg/ioutils/fswriters.go b/components/engine/pkg/ioutils/fswriters.go -index 534d66ac26..093f11ad8e 100644 ---- a/components/engine/pkg/ioutils/fswriters.go -+++ b/components/engine/pkg/ioutils/fswriters.go -@@ -5,6 +5,9 @@ import ( - "io/ioutil" - "os" - "path/filepath" -+ "strings" -+ -+ "github.com/sirupsen/logrus" - ) - - // NewAtomicFileWriter returns WriteCloser so that writing to it writes to a -@@ -27,6 +30,39 @@ func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, err - }, nil - } - -+func CleanupTmpFilesRecursive(rootDir string) { -+ var removals []string -+ filepath.Walk(rootDir, func(path string, f os.FileInfo, err error) error { -+ if strings.HasPrefix(f.Name(), ".tmp-") { -+ removals = append(removals, path) -+ } -+ return nil -+ }) -+ -+ for _, r := range removals { -+ os.RemoveAll(r) -+ } -+} -+ -+// CleanupAtomicFile cleanup redundant atomic files -+func CleanupAtomicFile(filename string) error { -+ baseName := ".tmp-" + filepath.Base(filename) -+ dir := filepath.Dir(filename) -+ fs, err := ioutil.ReadDir(dir) -+ if err != nil { -+ logrus.Errorf("open directory(%s) failed: %s", dir, err) -+ return err -+ } -+ -+ for _, f := range fs { -+ if strings.Contains(f.Name(), baseName) { -+ logrus.Warnf("Remove temporary file: %s", filepath.Join(dir, f.Name())) -+ os.RemoveAll(filepath.Join(dir, f.Name())) -+ } -+ } -+ return nil -+} -+ - // AtomicWriteFile atomically writes data to a file named by filename. - func AtomicWriteFile(filename string, data []byte, perm os.FileMode) error { - f, err := NewAtomicFileWriter(filename, perm) -diff --git a/components/engine/reference/store.go b/components/engine/reference/store.go -index b01051bf58..e54f772b5e 100644 ---- a/components/engine/reference/store.go -+++ b/components/engine/reference/store.go -@@ -81,6 +81,7 @@ func NewReferenceStore(jsonPath string) (Store, error) { - Repositories: make(map[string]repository), - referencesByIDCache: make(map[digest.Digest]map[string]reference.Named), - } -+ ioutils.CleanupAtomicFile(abspath) - // Load the json file if it exists, otherwise create it. - if err := store.reload(); os.IsNotExist(err) { - if err := store.save(); err != nil { --- -2.17.1 - diff --git a/patch/0021-umask-support-specify-umask.patch b/patch/0021-umask-support-specify-umask.patch deleted file mode 100644 index ee22ec4..0000000 --- a/patch/0021-umask-support-specify-umask.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 79b46d05b185bf8df96cabb2a121186cd2f121c3 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:22:35 +0800 -Subject: [PATCH 021/111] umask: support specify umask - -reason: support specify umask. -Umask can be 0022 or 0027(default) by specify umask when -start container by command `docker create/run` or start -daemon by command `dockerd`. For example: -$ dockerd --annotation native.umask=normal -$ dockerd --annotation native.umask=secure -$ docker run --exec-opt native.umask=normal -$ docker run --exec-opt native.umask=secure -`normal` reparent umask is 0022, `secure` -reparent umask is 0027. - -Change-Id: Iba07a884b733b411e5268d7ecaa22b9aa327ac3c -Signed-off-by: wangfengtu -Signed-off-by: lujingxiao ---- - components/engine/daemon/create.go | 21 +++++++++++++++- - components/engine/daemon/daemon_unix.go | 33 +++++++++++++++++++++++++ - 2 files changed, 53 insertions(+), 1 deletion(-) - -diff --git a/components/engine/daemon/create.go b/components/engine/daemon/create.go -index 565e9dc022..fa000c2208 100644 ---- a/components/engine/daemon/create.go -+++ b/components/engine/daemon/create.go -@@ -79,6 +79,22 @@ func (daemon *Daemon) containerCreate(params types.ContainerCreateConfig, manage - return containertypes.ContainerCreateCreatedBody{ID: container.ID, Warnings: warnings}, nil - } - -+func (daemon *Daemon) setUmask(c *containertypes.Config) error { -+ // Use option native.umask passed by command create/run if specified, -+ // otherwise use daemon's native.umask option. -+ if val, ok := c.Annotations["native.umask"]; ok { -+ if val != umaskNormal && val != umaskSecure { -+ return fmt.Errorf("native.umask option %s not supported", val) -+ } -+ } else if UsingNormalUmask(daemon.configStore) { -+ c.Annotations["native.umask"] = umaskNormal -+ } else { -+ c.Annotations["native.umask"] = umaskSecure -+ } -+ -+ return nil -+} -+ - // Create creates a new container from the given configuration with a given name. - func (daemon *Daemon) create(params types.ContainerCreateConfig, managed bool) (retC *container.Container, retErr error) { - var ( -@@ -162,8 +178,11 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig, managed bool) ( - } - container.RWLayer = rwLayer - -- rootIDs := daemon.idMapping.RootPair() -+ if err := daemon.setUmask(params.Config); err != nil { -+ return nil, err -+ } - -+ rootIDs := daemon.idMapping.RootPair() - if err := idtools.MkdirAndChown(container.Root, 0700, rootIDs); err != nil { - return nil, err - } -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index 5b390d2db1..8ffdd0009a 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -77,6 +77,10 @@ const ( - // DefaultRuntimeName is the default runtime to be used by - // containerd if none is specified - DefaultRuntimeName = "runc" -+ -+ // constant for umasks in containers. normal: 0022, secure(default): 0027 -+ umaskNormal = "normal" -+ umaskSecure = "secure" - ) - - type containerGetter interface { -@@ -581,6 +585,32 @@ func UsingSystemd(config *config.Config) bool { - return getCD(config) == cgroupSystemdDriver - } - -+// getUmask gets the raw value of the native.umask option, if set. -+func getUmask(config *config.Config) string { -+ for _, option := range config.ExecOptions { -+ key, val, err := parsers.ParseKeyValueOpt(option) -+ if err != nil || !strings.EqualFold(key, "native.umask") { -+ continue -+ } -+ return val -+ } -+ return "" -+} -+ -+// VerifyNativeUmask validates native.umask -+func VerifyNativeUmask(config *config.Config) error { -+ umask := getUmask(config) -+ if umask == "" || umask == umaskNormal || umask == umaskSecure { -+ return nil -+ } -+ return fmt.Errorf("native.umask option %s not supported", umask) -+} -+ -+// UsingNormalUmask returns true if cli option includes native.umask=normal -+func UsingNormalUmask(config *config.Config) bool { -+ return getUmask(config) == umaskNormal -+} -+ - // verifyPlatformContainerSettings performs platform-specific validation of the - // hostconfig and config structures. - func (daemon *Daemon) verifyPlatformContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) { -@@ -737,6 +767,9 @@ func verifyDaemonSettings(conf *config.Config) error { - return fmt.Errorf("cgroup-parent for systemd cgroup should be a valid slice named as \"xxx.slice\"") - } - } -+ if err := VerifyNativeUmask(conf); err != nil { -+ return err -+ } - - if conf.DefaultRuntime == "" { - conf.DefaultRuntime = config.StockRuntimeName --- -2.17.1 - diff --git a/patch/0022-umask-fix-nil-pointer-on-c.Annotations-in-set.patch b/patch/0022-umask-fix-nil-pointer-on-c.Annotations-in-set.patch deleted file mode 100644 index c0b5da0..0000000 --- a/patch/0022-umask-fix-nil-pointer-on-c.Annotations-in-set.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 412b8a34a2aa40ddf6f9b507142c4793922cedf5 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 11:22:46 +0800 -Subject: [PATCH 022/111] umask: fix nil pointer on c.Annotations in - setUmask - -reason: c.Annotations should be check before using in setUmask(). -When "/create" request is sent via restful api, the c.Annotations -is nil, so **nil map** happens in setUmask. - -Change-Id: Idafa2d8d1f54c1ebc34a6380d64c1cd7efad0266 -Signed-off-by: lujingxiao ---- - components/engine/daemon/create.go | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/components/engine/daemon/create.go b/components/engine/daemon/create.go -index fa000c2208..b57b01eacc 100644 ---- a/components/engine/daemon/create.go -+++ b/components/engine/daemon/create.go -@@ -86,10 +86,15 @@ func (daemon *Daemon) setUmask(c *containertypes.Config) error { - if val != umaskNormal && val != umaskSecure { - return fmt.Errorf("native.umask option %s not supported", val) - } -- } else if UsingNormalUmask(daemon.configStore) { -- c.Annotations["native.umask"] = umaskNormal - } else { -- c.Annotations["native.umask"] = umaskSecure -+ if c.Annotations == nil { -+ c.Annotations = make(map[string]string) -+ } -+ if UsingNormalUmask(daemon.configStore) { -+ c.Annotations["native.umask"] = umaskNormal -+ } else { -+ c.Annotations["native.umask"] = umaskSecure -+ } - } - - return nil --- -2.17.1 - diff --git a/patch/0023-prjquota-fix-syscall-bugs-in-projectquota.patch b/patch/0023-prjquota-fix-syscall-bugs-in-projectquota.patch deleted file mode 100644 index ef984df..0000000 --- a/patch/0023-prjquota-fix-syscall-bugs-in-projectquota.patch +++ /dev/null @@ -1,65 +0,0 @@ -From d864d32460063a25ef5a408c596b40555a062646 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 15:02:39 +0800 -Subject: [PATCH 023/111] prjquota: fix syscall bugs in projectquota - -reason: fix syscall bugs in projectquota, which is introduced -when cherry-picked. - -Change-Id: I4496f2b8fcdcd16eb34584b435a9ef9434639cee -Signed-off-by: lujingxiao ---- - .../engine/daemon/graphdriver/quota/projectquota.go | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - -diff --git a/components/engine/daemon/graphdriver/quota/projectquota.go b/components/engine/daemon/graphdriver/quota/projectquota.go -index 7d879eb81d..7f2fa2fe70 100644 ---- a/components/engine/daemon/graphdriver/quota/projectquota.go -+++ b/components/engine/daemon/graphdriver/quota/projectquota.go -@@ -79,7 +79,6 @@ import ( - "path" - "path/filepath" - "sync" -- "syscall" - "unsafe" - - rsystem "github.com/opencontainers/runc/libcontainer/system" -@@ -234,7 +233,7 @@ func (q *Control) SetQuota(targetPath string, quota Quota) error { - // - err := setProjectID(targetPath, projectID) - if err != nil { -- q.lock.Lock() -+ q.lock.Unlock() - return err - } - -@@ -312,7 +311,7 @@ func (q *Ext4Quota) SetProjectQuota(backingFsBlockDev string, projectID uint32, - var cs = C.CString(backingFsBlockDev) - defer C.free(unsafe.Pointer(cs)) - -- _, _, errno := syscall.Syscall6(syscall.SYS_QUOTACTL, C.Q_SETPQUOTA, -+ _, _, errno := unix.Syscall6(unix.SYS_QUOTACTL, C.Q_SETPQUOTA, - uintptr(unsafe.Pointer(cs)), uintptr(C.__u32(projectID)), - uintptr(unsafe.Pointer(&d)), 0, 0) - if errno != 0 { -@@ -330,7 +329,7 @@ func (q *Ext4Quota) GetProjectQuota(backingFsBlockDev string, projectID uint32, - var cs = C.CString(backingFsBlockDev) - defer C.free(unsafe.Pointer(cs)) - -- _, _, errno := syscall.Syscall6(syscall.SYS_QUOTACTL, C.Q_SETPQUOTA, -+ _, _, errno := unix.Syscall6(unix.SYS_QUOTACTL, C.Q_GETPQUOTA, - uintptr(unsafe.Pointer(cs)), uintptr(C.__u32(projectID)), - uintptr(unsafe.Pointer(&d)), 0, 0) - if errno != 0 { -@@ -350,7 +349,7 @@ func getQuotaStat(backingFsBlockDev string) (int, error) { - - var cs = C.CString(backingFsBlockDev) - defer C.free(unsafe.Pointer(cs)) -- _, _, errno := syscall.Syscall6(syscall.SYS_QUOTACTL, C.Q_XGETPQSTAT, -+ _, _, errno := unix.Syscall6(unix.SYS_QUOTACTL, C.Q_XGETPQSTAT, - uintptr(unsafe.Pointer(cs)), 0, - uintptr(unsafe.Pointer(&info)), 0, 0) - if errno != 0 { --- -2.17.1 - diff --git a/patch/0024-runtime-spec-Compatibility-modifications-fo.patch b/patch/0024-runtime-spec-Compatibility-modifications-fo.patch deleted file mode 100644 index cc3f8c8..0000000 --- a/patch/0024-runtime-spec-Compatibility-modifications-fo.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 3de51170031133bcd8d6aefe022d3fd26287c8c0 Mon Sep 17 00:00:00 2001 -From: leizhongkai -Date: Sat, 19 Jan 2019 16:45:43 +0800 -Subject: [PATCH 024/111] runtime-spec: Compatibility modifications - for runc-1.0.0-rc3 about `struct LinuxBlockIO` - -reason:Compatibility modifications for runc-1.0.0-rc3 about `struct LinuxBlockIO` - -Change-Id: If2389709d4639b5e9d61a9b853a8f220ef6e3884 -Signed-off-by: leizhongkai ---- - .../runtime-spec/specs-go/config.go | 18 +++++++++--------- - 2 files changed, 10 insertions(+), 9 deletions(-) - -diff --git a/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go -index 46049b3bfa..aab7b8a098 100644 ---- a/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go -+++ b/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go -@@ -256,20 +256,20 @@ type LinuxThrottleDevice struct { - - // LinuxBlockIO for Linux cgroup 'blkio' resource management - type LinuxBlockIO struct { -- // Specifies per cgroup weight -- Weight *uint16 `json:"weight,omitempty"` -- // Specifies tasks' weight in the given cgroup while competing with the cgroup's child cgroups, CFQ scheduler only -- LeafWeight *uint16 `json:"leafWeight,omitempty"` -+ // Specifies per cgroup weight, range is from 10 to 1000 -+ Weight *uint16 `json:"blkioWeight,omitempty"` -+ // Specifies tasks' weight in the given cgroup while competing with the cgroup's child cgroups, range is from 10 to 1000, CFQ scheduler only -+ LeafWeight *uint16 `json:"blkioLeafWeight,omitempty"` - // Weight per cgroup per device, can override BlkioWeight -- WeightDevice []LinuxWeightDevice `json:"weightDevice,omitempty"` -+ WeightDevice []LinuxWeightDevice `json:"blkioWeightDevice,omitempty"` - // IO read rate limit per cgroup per device, bytes per second -- ThrottleReadBpsDevice []LinuxThrottleDevice `json:"throttleReadBpsDevice,omitempty"` -+ ThrottleReadBpsDevice []LinuxThrottleDevice `json:"blkioThrottleReadBpsDevice,omitempty"` - // IO write rate limit per cgroup per device, bytes per second -- ThrottleWriteBpsDevice []LinuxThrottleDevice `json:"throttleWriteBpsDevice,omitempty"` -+ ThrottleWriteBpsDevice []LinuxThrottleDevice `json:"blkioThrottleWriteBpsDevice,omitempty"` - // IO read rate limit per cgroup per device, IO per second -- ThrottleReadIOPSDevice []LinuxThrottleDevice `json:"throttleReadIOPSDevice,omitempty"` -+ ThrottleReadIOPSDevice []LinuxThrottleDevice `json:"blkioThrottleReadIOPSDevice,omitempty"` - // IO write rate limit per cgroup per device, IO per second -- ThrottleWriteIOPSDevice []LinuxThrottleDevice `json:"throttleWriteIOPSDevice,omitempty"` -+ ThrottleWriteIOPSDevice []LinuxThrottleDevice `json:"blkioThrottleWriteIOPSDevice,omitempty"` - } - - // LinuxMemory for Linux cgroup 'memory' resource management --- -2.17.1 - diff --git a/patch/0025-resource-limit-enable-unlimited-usage-of-memo.patch b/patch/0025-resource-limit-enable-unlimited-usage-of-memo.patch deleted file mode 100644 index 998b1ef..0000000 --- a/patch/0025-resource-limit-enable-unlimited-usage-of-memo.patch +++ /dev/null @@ -1,44 +0,0 @@ -From d0625f253c9cfd62e043f1799b9f9c2a0e2fdb21 Mon Sep 17 00:00:00 2001 -From: caihaomin -Date: Sun, 20 Jan 2019 13:59:45 +0800 -Subject: [PATCH 025/111] resource-limit: enable unlimited usage of - memory compoents - -reason:enable unlimited usage of memory compoents - -Change-Id: I24871d1b2ef1fe20277d5e5c721d1297fa5fd6cf -Signed-off-by: caihaomin ---- - components/engine/container/container_unix.go | 2 +- - components/engine/daemon/update_linux.go | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/components/engine/container/container_unix.go b/components/engine/container/container_unix.go -index ed664f3eec..5a21b8c483 100644 ---- a/components/engine/container/container_unix.go -+++ b/components/engine/container/container_unix.go -@@ -323,7 +323,7 @@ func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfi - if resources.Memory != 0 { - // if memory limit smaller than already set memoryswap limit and doesn't - // update the memoryswap limit, then error out. -- if resources.Memory > cResources.MemorySwap && resources.MemorySwap == 0 { -+ if cResources.MemorySwap > 0 && resources.Memory > cResources.MemorySwap && resources.MemorySwap == 0 { - return conflictingUpdateOptions("Memory limit should be smaller than already set memoryswap limit, update the memoryswap at the same time") - } - cResources.Memory = resources.Memory -diff --git a/components/engine/daemon/update_linux.go b/components/engine/daemon/update_linux.go -index 6a307eabc5..1a6f070b82 100644 ---- a/components/engine/daemon/update_linux.go -+++ b/components/engine/daemon/update_linux.go -@@ -46,7 +46,7 @@ func toContainerdResources(resources container.Resources) *libcontainerd.Resourc - Kernel: &resources.KernelMemory, - } - -- if resources.MemorySwap > 0 { -+ if resources.MemorySwap != 0 { - r.Memory.Swap = &resources.MemorySwap - } - --- -2.17.1 - diff --git a/patch/0026-prjquota-use-dockerd-quota-size-when-docker.patch b/patch/0026-prjquota-use-dockerd-quota-size-when-docker.patch deleted file mode 100644 index f7801e0..0000000 --- a/patch/0026-prjquota-use-dockerd-quota-size-when-docker.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0ff4db1fc19ecb6f9dedfaa8d0645a638bb7ab20 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Sat, 19 Jan 2019 17:53:59 +0800 -Subject: [PATCH 026/111] prjquota: use dockerd quota size when - docker not specifies - -reason: if docker run not specifies quota size but dockerd has default -size, we should use the default value in dockerd. -EulerOS docker 1.11.2 and 17.06 has the same logic. But now, if docker -create/run not give --storage-opt, it will panic during parseStorageOpt, so -updating the handling logic. - -Change-Id: I52141c7f1caf5a2a4cbd9c00fbe709f09f7a412b -Signed-off-by: lujingxiao ---- - .../engine/daemon/graphdriver/overlay2/overlay.go | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index 7290616bae..722d65b11a 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -406,6 +406,11 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr - return err - } - } -+ } else if d.options.quota.Size > 0 { -+ // docker run not specified quota size, but dockerd does, so limits it also -+ if err := d.quotaCtl.SetQuota(dir, d.options.quota); err != nil { -+ return err -+ } - } - - if err := idtools.MkdirAndChown(path.Join(dir, "diff"), 0755, root); err != nil { --- -2.17.1 - diff --git a/patch/0027-oci-add-files_panic_enable-to-masked-path.patch b/patch/0027-oci-add-files_panic_enable-to-masked-path.patch deleted file mode 100644 index a526dea..0000000 --- a/patch/0027-oci-add-files_panic_enable-to-masked-path.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 5370b3b9f2f4adfc10bbc3db5903b1a23e13f6c2 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 9 Jan 2019 00:37:17 +0800 -Subject: [PATCH 027/111] oci: add files_panic_enable to masked path - -reason: cherry-pick commits to docker-18.09 - -reason:add files_panic_enable to masked path - -Change-Id: I3d6fb04a1063f64ad52e40cb5debf21c301d829c -Signed-off-by: xiadanni ---- - components/engine/oci/defaults.go | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/components/engine/oci/defaults.go b/components/engine/oci/defaults.go -index 5e17ea3f38..e39140b47f 100644 ---- a/components/engine/oci/defaults.go -+++ b/components/engine/oci/defaults.go -@@ -123,6 +123,7 @@ func DefaultLinuxSpec() specs.Spec { - "/proc/timer_stats", - "/proc/sched_debug", - "/proc/scsi", -+ "/proc/files_panic_enable", - "/sys/firmware", - }, - ReadonlyPaths: []string{ --- -2.17.1 - diff --git a/patch/0028-oci-add-fdenable-fdstat-and-fdthreshold-to-ma.patch b/patch/0028-oci-add-fdenable-fdstat-and-fdthreshold-to-ma.patch deleted file mode 100644 index 4b444cb..0000000 --- a/patch/0028-oci-add-fdenable-fdstat-and-fdthreshold-to-ma.patch +++ /dev/null @@ -1,34 +0,0 @@ -From f81a87edbeb1ddc58d48d36c963f76f0ed6cc04f Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 9 Jan 2019 00:40:29 +0800 -Subject: [PATCH 028/111] oci: add fdenable fdstat and fdthreshold to - masked path - -reason: cherry-pick commits to docker-18.09 - -reason:add fdenable fdstat and fdthreshold to masked path - -Change-Id: I7b39a4ad9b989ef4b8185e386aa70c2d638efcd9 -Signed-off-by: caihaomin -Signed-off-by: xiadanni ---- - components/engine/oci/defaults.go | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/components/engine/oci/defaults.go b/components/engine/oci/defaults.go -index e39140b47f..de0088c4bb 100644 ---- a/components/engine/oci/defaults.go -+++ b/components/engine/oci/defaults.go -@@ -124,6 +124,9 @@ func DefaultLinuxSpec() specs.Spec { - "/proc/sched_debug", - "/proc/scsi", - "/proc/files_panic_enable", -+ "/proc/fdthreshold", -+ "/proc/fdstat", -+ "/proc/fdenable", - "/sys/firmware", - }, - ReadonlyPaths: []string{ --- -2.17.1 - diff --git a/patch/0029-oci-add-oom_extend-to-proc-masked-path.patch b/patch/0029-oci-add-oom_extend-to-proc-masked-path.patch deleted file mode 100644 index b92787c..0000000 --- a/patch/0029-oci-add-oom_extend-to-proc-masked-path.patch +++ /dev/null @@ -1,43 +0,0 @@ -From fe4522af7f1c5dadfeaf8513dd584c66854d612b Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 9 Jan 2019 00:43:55 +0800 -Subject: [PATCH 029/111] oci: add oom_extend to proc masked path - -reason: cherry-pick commits to docker-18.09 - -reason:add oom_extend to proc masked path - -Change-Id: I4b9c3dd94b6d68d753e9aad0879949b310fe7180 -Signed-off-by: dengguangxing -Signed-off-by: Haomin -Signed-off-by: xiadanni ---- - components/engine/oci/defaults.go | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/components/engine/oci/defaults.go b/components/engine/oci/defaults.go -index de0088c4bb..74d3fdb2d8 100644 ---- a/components/engine/oci/defaults.go -+++ b/components/engine/oci/defaults.go -@@ -116,6 +116,7 @@ func DefaultLinuxSpec() specs.Spec { - s.Linux = &specs.Linux{ - MaskedPaths: []string{ - "/proc/acpi", -+ "/proc/config.gz", - "/proc/kcore", - "/proc/keys", - "/proc/latency_stats", -@@ -127,6 +128,10 @@ func DefaultLinuxSpec() specs.Spec { - "/proc/fdthreshold", - "/proc/fdstat", - "/proc/fdenable", -+ "/proc/signo", -+ "/proc/sig_catch", -+ "/proc/kbox", -+ "/proc/oom_extend", - "/sys/firmware", - }, - ReadonlyPaths: []string{ --- -2.17.1 - diff --git a/patch/0030-restart-fix-docker-stats-blocked-while-docker.patch b/patch/0030-restart-fix-docker-stats-blocked-while-docker.patch deleted file mode 100644 index 70052ad..0000000 --- a/patch/0030-restart-fix-docker-stats-blocked-while-docker.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 1e9ad6a48e283bcc9850fb1439bf0be6be805010 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 9 Jan 2019 00:49:35 +0800 -Subject: [PATCH 030/111] restart: fix docker stats blocked while - docker daemon restart - -reason: cherry-pick commits to docker-18.09 - -change closeChan channel from non-buffered channel to 2-buffered channel, - because non-blocked channel will be blocked while docker daemon restart - -Change-Id: Ica5dbefc85e463836b55e5d96da522a64a259f64 -Signed-off-by: jiangpengfei9 -Signed-off-by: xiadanni ---- - components/cli/cli/command/container/stats.go | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/components/cli/cli/command/container/stats.go b/components/cli/cli/command/container/stats.go -index 4efcb19e65..1f9e1b8556 100644 ---- a/components/cli/cli/command/container/stats.go -+++ b/components/cli/cli/command/container/stats.go -@@ -53,7 +53,7 @@ func NewStatsCommand(dockerCli command.Cli) *cobra.Command { - // nolint: gocyclo - func runStats(dockerCli command.Cli, opts *statsOptions) error { - showAll := len(opts.containers) == 0 -- closeChan := make(chan error) -+ closeChan := make(chan error, 2) - - ctx := context.Background() - --- -2.17.1 - diff --git a/patch/0031-restart-Incase-deadlock-when-kill-the-docker-.patch b/patch/0031-restart-Incase-deadlock-when-kill-the-docker-.patch deleted file mode 100644 index 0360efa..0000000 --- a/patch/0031-restart-Incase-deadlock-when-kill-the-docker-.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 6da7401bff6b59e59f04323fcf2f88115f38ede8 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 9 Jan 2019 16:33:11 +0800 -Subject: [PATCH 031/111] restart: Incase deadlock when kill the docker - CLI and restart - -reason: cherry-pick commits to docker-18.09 - -the docker daemon is in created stage and last long time, then kill -the docker cli and restart docker at the same time, the restart stage will trylock, -because the created stage already locked. - -cherry-pick from 1.11.2: 3082432 - -the testcase testCE_container_resourced_cpuiso_ABN.023.sh - - current_dir=$(cd `dirname $0` && pwd) - source ${COMMON_DIR}/commonlib.sh - source ${current_dir}/../common/container_resourced_commonlib.sh - resource_managerd_env - - work_dir=`mktemp -d /tmp/testCE_container_resourced_cpuiso_ABN_005.XXXX` - bind_cpu=1 - resource_pid=`ps axu |grep resource-managerd |grep -v grep|awk '{print $2}'` - service container-resourced stop - service container-resourced start & kill -9 $! - container_id=`timeout 10 docker run -itd --hook-spec /etc/docker/resource-hook.json --cpuset-cpus $bind_cpu -e ISOLATION_CORES=$bind_cpu $ubuntu_image bash &` - timeout 10 docker restart $container_id - fn_check_result_noeq $? 0 - resource_managerd_env - docker restart $container_id - fn_check_result $? 0 - test_cpuset $container_id - docker rm -f $container_id - rm -rf $work_dir - kill_resource_managerd - exit $exit_flag -Conflicts: - daemon/restart.go - -Change-Id: I571f109dc07a7e76df40c544008a97cd497ef8bb -Signed-off-by: panwenxiang -Signed-off-by: lixiang172 ---- - components/engine/daemon/restart.go | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/components/engine/daemon/restart.go b/components/engine/daemon/restart.go -index 0f06dea267..bae665f76b 100644 ---- a/components/engine/daemon/restart.go -+++ b/components/engine/daemon/restart.go -@@ -41,7 +41,10 @@ func (daemon *Daemon) containerRestart(container *container.Container, seconds i - defer daemon.Unmount(container) - } - -- if container.IsRunning() { -+ if container.RemovalInProgress || container.Dead { -+ return fmt.Errorf("can't restart a container which is dead or marked for removal") -+ } -+ if container.Running { - // set AutoRemove flag to false before stop so the container won't be - // removed during restart process - autoRemove := container.HostConfig.AutoRemove --- -2.17.1 - diff --git a/patch/0032-devmapper-Add-udev-event-time-out-to-fix-dock.patch b/patch/0032-devmapper-Add-udev-event-time-out-to-fix-dock.patch deleted file mode 100644 index b2c8c04..0000000 --- a/patch/0032-devmapper-Add-udev-event-time-out-to-fix-dock.patch +++ /dev/null @@ -1,254 +0,0 @@ -From e22807e3972f1c168e596fa95a97e2730024824c Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 3 Jan 2019 10:20:44 +0800 -Subject: [PATCH 032/111] devmapper: Add udev event time out to fix - docker stuck on udev wait - -reason: cherry-pick commits to docker-18.09 - -Add udev event time out to fix docker stuck on udev wait - -Change-Id: I47505140699c0a51f37f4127b761f2a99930466d -Signed-off-by: jingrui ---- - .../daemon/graphdriver/devmapper/deviceset.go | 28 ++++++--- - .../engine/pkg/devicemapper/devmapper.go | 57 +++++++++++++------ - .../pkg/devicemapper/devmapper_wrapper.go | 5 ++ - 3 files changed, 66 insertions(+), 24 deletions(-) - -diff --git a/components/engine/daemon/graphdriver/devmapper/deviceset.go b/components/engine/daemon/graphdriver/devmapper/deviceset.go -index 5dc01d71d9..af53cf83e6 100644 ---- a/components/engine/daemon/graphdriver/devmapper/deviceset.go -+++ b/components/engine/daemon/graphdriver/devmapper/deviceset.go -@@ -35,13 +35,16 @@ import ( - ) - - var ( -- defaultDataLoopbackSize int64 = 100 * 1024 * 1024 * 1024 -- defaultMetaDataLoopbackSize int64 = 2 * 1024 * 1024 * 1024 -- defaultBaseFsSize uint64 = 10 * 1024 * 1024 * 1024 -- defaultThinpBlockSize uint32 = 128 // 64K = 128 512b sectors -- defaultUdevSyncOverride = false -- maxDeviceID = 0xffffff // 24 bit, pool limit -- deviceIDMapSz = (maxDeviceID + 1) / 8 -+ defaultDataLoopbackSize int64 = 100 * 1024 * 1024 * 1024 -+ defaultMetaDataLoopbackSize int64 = 2 * 1024 * 1024 * 1024 -+ defaultBaseFsSize uint64 = 10 * 1024 * 1024 * 1024 -+ defaultThinpBlockSize uint32 = 128 // 64K = 128 512b sectors -+ defaultUdevSyncOverride = false -+ maxDeviceID = 0xffffff // 24 bit, pool limit -+ deviceIDMapSz = (maxDeviceID + 1) / 8 -+ // The default timeout is 30s from `man systemd-udevd`, we use 35 -+ // just to make sure the timeout really happened in systemd-udevd -+ defaultUdevWaitTimeout = 35 - driverDeferredRemovalSupport = false - enableDeferredRemoval = false - enableDeferredDeletion = false -@@ -2059,7 +2062,9 @@ func (devices *DeviceSet) issueDiscard(info *devInfo) error { - // Should be called with devices.Lock() held. - func (devices *DeviceSet) deleteDevice(info *devInfo, syncDelete bool) error { - if devices.doBlkDiscard { -- devices.issueDiscard(info) -+ if err := devices.issueDiscard(info); err != nil { -+ return err -+ } - } - - // Try to deactivate device in case it is active. -@@ -2651,6 +2656,7 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [ - - foundBlkDiscard := false - var lvmSetupConfig directLVMConfig -+ udevWaitTimeout := int64(defaultUdevWaitTimeout) - for _, option := range options { - key, val, err := parsers.ParseKeyValueOpt(option) - if err != nil { -@@ -2800,10 +2806,16 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [ - devicemapper.LogInit(devicemapper.DefaultLogger{ - Level: int(level), - }) -+ case "dm.udev_wait_timeout": -+ udevWaitTimeout, err = strconv.ParseInt(val, 10, 32) -+ if err != nil { -+ return nil, err -+ } - default: - return nil, fmt.Errorf("devmapper: Unknown option %s", key) - } - } -+ devicemapper.SetUdevWaitTimtout(udevWaitTimeout) - - if err := validateLVMConfig(lvmSetupConfig); err != nil { - return nil, err -diff --git a/components/engine/pkg/devicemapper/devmapper.go b/components/engine/pkg/devicemapper/devmapper.go -index 63243637a7..b384a27f8f 100644 ---- a/components/engine/pkg/devicemapper/devmapper.go -+++ b/components/engine/pkg/devicemapper/devmapper.go -@@ -7,6 +7,7 @@ import ( - "fmt" - "os" - "runtime" -+ "time" - "unsafe" - - "github.com/sirupsen/logrus" -@@ -59,6 +60,7 @@ var ( - ErrNilCookie = errors.New("cookie ptr can't be nil") - ErrGetBlockSize = errors.New("Can't get block size") - ErrUdevWait = errors.New("wait on udev cookie failed") -+ ErrUdevWaitTimeout = errors.New("wait on udev cookie time out") - ErrSetDevDir = errors.New("dm_set_dev_dir failed") - ErrGetLibraryVersion = errors.New("dm_get_library_version failed") - ErrCreateRemoveTask = errors.New("Can't create task of type deviceRemove") -@@ -71,10 +73,11 @@ var ( - ) - - var ( -- dmSawBusy bool -- dmSawExist bool -- dmSawEnxio bool // No Such Device or Address -- dmSawEnoData bool // No data available -+ dmSawBusy bool -+ dmSawExist bool -+ dmSawEnxio bool // No Such Device or Address -+ dmSawEnoData bool // No data available -+ dmUdevWaitTimeout int64 - ) - - type ( -@@ -256,13 +259,36 @@ func (t *Task) getNextTarget(next unsafe.Pointer) (nextPtr unsafe.Pointer, start - - // UdevWait waits for any processes that are waiting for udev to complete the specified cookie. - func UdevWait(cookie *uint) error { -- if res := DmUdevWait(*cookie); res != 1 { -- logrus.Debugf("devicemapper: Failed to wait on udev cookie %d, %d", *cookie, res) -- return ErrUdevWait -+ chError := make(chan error) -+ go func() { -+ if res := DmUdevWait(*cookie); res != 1 { -+ logrus.Debugf("Failed to wait on udev cookie %d", *cookie) -+ chError <- ErrUdevWait -+ } -+ chError <- nil -+ }() -+ select { -+ case err := <-chError: -+ return err -+ case <-time.After(time.Second * time.Duration(dmUdevWaitTimeout)): -+ logrus.Errorf("Failed to wait on udev cookie %d: timeout %v", *cookie, dmUdevWaitTimeout) -+ if res := DmUdevComplete(*cookie); res != 1 { -+ // This is bad to return here -+ logrus.Errorf("Failed to complete udev cookie %d on udev wait timeout", *cookie) -+ return ErrUdevWaitTimeout -+ } -+ // wait DmUdevWait return after DmUdevComplete -+ <-chError -+ return ErrUdevWaitTimeout - } - return nil - } - -+// SetUdevWaitTimtout sets udev wait timeout -+func SetUdevWaitTimtout(t int64) { -+ dmUdevWaitTimeout = t -+} -+ - // SetDevDir sets the dev folder for the device mapper library (usually /dev). - func SetDevDir(dir string) error { - if res := DmSetDevDir(dir); res != 1 { -@@ -319,11 +345,11 @@ func RemoveDevice(name string) error { - if err := task.setCookie(cookie, 0); err != nil { - return fmt.Errorf("devicemapper: Can not set cookie: %s", err) - } -- defer UdevWait(cookie) - - dmSawBusy = false // reset before the task is run - dmSawEnxio = false - if err = task.run(); err != nil { -+ UdevWait(cookie) - if dmSawBusy { - return ErrBusy - } -@@ -333,7 +359,7 @@ func RemoveDevice(name string) error { - return fmt.Errorf("devicemapper: Error running RemoveDevice %s", err) - } - -- return nil -+ return UdevWait(cookie) - } - - // RemoveDeviceDeferred is a useful helper for cleaning up a device, but deferred. -@@ -470,13 +496,13 @@ func CreatePool(poolName string, dataFile, metadataFile *os.File, poolBlockSize - if err := task.setCookie(cookie, flags); err != nil { - return fmt.Errorf("devicemapper: Can't set cookie %s", err) - } -- defer UdevWait(cookie) - - if err := task.run(); err != nil { -+ UdevWait(cookie) - return fmt.Errorf("devicemapper: Error running deviceCreate (CreatePool) %s", err) - } - -- return nil -+ return UdevWait(cookie) - } - - // ReloadPool is the programmatic example of "dmsetup reload". -@@ -656,13 +682,13 @@ func ResumeDevice(name string) error { - if err := task.setCookie(cookie, 0); err != nil { - return fmt.Errorf("devicemapper: Can't set cookie %s", err) - } -- defer UdevWait(cookie) - - if err := task.run(); err != nil { -+ UdevWait(cookie) - return fmt.Errorf("devicemapper: Error running deviceResume %s", err) - } - -- return nil -+ return UdevWait(cookie) - } - - // CreateDevice creates a device with the specified poolName with the specified device id. -@@ -760,13 +786,12 @@ func activateDevice(poolName string, name string, deviceID int, size uint64, ext - return fmt.Errorf("devicemapper: Can't set cookie %s", err) - } - -- defer UdevWait(cookie) -- - if err := task.run(); err != nil { -+ UdevWait(cookie) - return fmt.Errorf("devicemapper: Error running deviceCreate (ActivateDevice) %s", err) - } - -- return nil -+ return UdevWait(cookie) - } - - // CreateSnapDeviceRaw creates a snapshot device. Caller needs to suspend and resume the origin device if it is active. -diff --git a/components/engine/pkg/devicemapper/devmapper_wrapper.go b/components/engine/pkg/devicemapper/devmapper_wrapper.go -index 0b88f49695..77cd674a09 100644 ---- a/components/engine/pkg/devicemapper/devmapper_wrapper.go -+++ b/components/engine/pkg/devicemapper/devmapper_wrapper.go -@@ -77,6 +77,7 @@ var ( - DmTaskSetRo = dmTaskSetRoFct - DmTaskSetSector = dmTaskSetSectorFct - DmUdevWait = dmUdevWaitFct -+ DmUdevComplete = dmUdevCompleteFct - DmUdevSetSyncSupport = dmUdevSetSyncSupportFct - DmUdevGetSyncSupport = dmUdevGetSyncSupportFct - DmCookieSupported = dmCookieSupportedFct -@@ -227,6 +228,10 @@ func dmUdevWaitFct(cookie uint) int { - return int(C.dm_udev_wait(C.uint32_t(cookie))) - } - -+func dmUdevCompleteFct(cookie uint) int { -+ return int(C.dm_udev_complete(C.uint32_t(cookie))) -+} -+ - func dmCookieSupportedFct() int { - return int(C.dm_cookie_supported()) - } --- -2.17.1 - diff --git a/patch/0033-devmapper-Fix-devicemapper-issue-power-off-th.patch b/patch/0033-devmapper-Fix-devicemapper-issue-power-off-th.patch deleted file mode 100644 index 5e263bd..0000000 --- a/patch/0033-devmapper-Fix-devicemapper-issue-power-off-th.patch +++ /dev/null @@ -1,224 +0,0 @@ -From 72f9e0c4d0d907a036d25c9dfeea9c0baddddc3e Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 3 Jan 2019 10:37:50 +0800 -Subject: [PATCH 033/111] devmapper: Fix devicemapper issue: power off - the VM while loading a image, couldn't load it after VM bootup - -reason: cherry-pick commits to docker-18.09 - -cherry-pick from 28991928c4 | * Fix devicemapper issue: power off the VM while -loading a image, couldn't load it after VM bootup - -Issue Description: -While running loading image test, power off or restart the VM, and then -there are -some chances that we can not load the image. And "Error running -deviceCreate (createSnapDevice) dm_task_run failed" will be reported. - -Reproduce Steps: -> 1. run `docker load -i xxx.tar` -> 2. virsh restart VM; # restart the VM. -> 3. After startup, run `docker load -i xxx.tar`, will fail to import -> the image - -Analysis: -From syslog, we found that docker was executing "Umount Device" then VM -powered restart. And found -two failure reasons: -> 1. Rollback operation only remove the device on DM thin pool, not -> remove the device in memory -> 2. TransactionData or metadata not flushed to Disk. - -Solution: -> 1. Rollback operation for DM, should remove the devices cache in DM -> driver. -> 2. When restore layers and images, check whether the device exists in -> graphdriver. - If desen't, remove the layer( and the metadata) and do not load the -image. - -Issue link: - #203 - -Signed-off-by: Wentao Zhang - -Conflicts: - image/store.go - layer/layer_store.go - -Change-Id: If3bfbf0d0ed8f950cfd5934fc25fac892481275c -Signed-off-by: jingrui ---- - .../daemon/graphdriver/devmapper/deviceset.go | 38 +++++++------------ - components/engine/image/store.go | 3 +- - components/engine/layer/layer_store.go | 15 +++++++- - 3 files changed, 28 insertions(+), 28 deletions(-) - -diff --git a/components/engine/daemon/graphdriver/devmapper/deviceset.go b/components/engine/daemon/graphdriver/devmapper/deviceset.go -index af53cf83e6..0675b2eacd 100644 ---- a/components/engine/daemon/graphdriver/devmapper/deviceset.go -+++ b/components/engine/daemon/graphdriver/devmapper/deviceset.go -@@ -6,7 +6,6 @@ import ( - "bufio" - "encoding/json" - "fmt" -- "io" - "io/ioutil" - "os" - "os/exec" -@@ -23,6 +22,7 @@ import ( - "github.com/docker/docker/pkg/devicemapper" - "github.com/docker/docker/pkg/dmesg" - "github.com/docker/docker/pkg/idtools" -+ "github.com/docker/docker/pkg/ioutils" - "github.com/docker/docker/pkg/loopback" - "github.com/docker/docker/pkg/mount" - "github.com/docker/docker/pkg/parsers" -@@ -306,6 +306,10 @@ func (devices *DeviceSet) ensureImage(name string, size int64) (string, error) { - return filename, nil - } - -+func (devices *DeviceSet) removeDeviceMap(hash string) { -+ delete(devices.Devices, hash) -+} -+ - func (devices *DeviceSet) allocateTransactionID() uint64 { - devices.OpenTransactionID = devices.TransactionID + 1 - return devices.OpenTransactionID -@@ -328,28 +332,9 @@ func (devices *DeviceSet) removeMetadata(info *devInfo) error { - - // Given json data and file path, write it to disk - func (devices *DeviceSet) writeMetaFile(jsonData []byte, filePath string) error { -- tmpFile, err := ioutil.TempFile(devices.metadataDir(), ".tmp") -- if err != nil { -- return fmt.Errorf("devmapper: Error creating metadata file: %s", err) -- } -- -- n, err := tmpFile.Write(jsonData) -- if err != nil { -- return fmt.Errorf("devmapper: Error writing metadata to %s: %s", tmpFile.Name(), err) -- } -- if n < len(jsonData) { -- return io.ErrShortWrite -+ if err := ioutils.AtomicWriteFile(filePath, jsonData, 0600); err != nil { -+ return fmt.Errorf("devmapper: Error writing metadata to %s: %s", filePath, err) - } -- if err := tmpFile.Sync(); err != nil { -- return fmt.Errorf("devmapper: Error syncing metadata file %s: %s", tmpFile.Name(), err) -- } -- if err := tmpFile.Close(); err != nil { -- return fmt.Errorf("devmapper: Error closing metadata file %s: %s", tmpFile.Name(), err) -- } -- if err := os.Rename(tmpFile.Name(), filePath); err != nil { -- return fmt.Errorf("devmapper: Error committing metadata file %s: %s", tmpFile.Name(), err) -- } -- - return nil - } - -@@ -483,7 +468,7 @@ func (devices *DeviceSet) unregisterDevice(hash string) error { - Hash: hash, - } - -- delete(devices.Devices, hash) -+ devices.removeDeviceMap(hash) - - if err := devices.removeMetadata(info); err != nil { - logrus.WithField("storage-driver", "devicemapper").Debugf("Error removing metadata: %s", err) -@@ -509,7 +494,7 @@ func (devices *DeviceSet) registerDevice(id int, hash string, size uint64, trans - - if err := devices.saveMetadata(info); err != nil { - // Try to remove unused device -- delete(devices.Devices, hash) -+ devices.removeDeviceMap(hash) - return nil, err - } - -@@ -1173,7 +1158,7 @@ func (devices *DeviceSet) checkGrowBaseDeviceFS(info *devInfo) error { - - if err := devices.saveMetadata(info); err != nil { - // Try to remove unused device -- delete(devices.Devices, info.Hash) -+ devices.removeDeviceMap(info.Hash) - return err - } - -@@ -1401,6 +1386,8 @@ func (devices *DeviceSet) rollbackTransaction() error { - devices.markDeviceIDFree(devices.DeviceID) - } - -+ devices.removeDeviceMap(dinfo.Hash) -+ - if err := devices.removeTransactionMetaData(); err != nil { - logger.Errorf("Unable to remove transaction meta file %s: %s", devices.transactionMetaFile(), err) - } -@@ -1482,6 +1469,7 @@ func (devices *DeviceSet) closeTransaction() error { - logrus.WithField("storage-driver", "devicemapper").Debug("Failed to close Transaction") - return err - } -+ - return nil - } - -diff --git a/components/engine/image/store.go b/components/engine/image/store.go -index 1a8a8a2451..b078a2627a 100644 ---- a/components/engine/image/store.go -+++ b/components/engine/image/store.go -@@ -81,8 +81,9 @@ func (is *store) restore() error { - } - l, err = is.lss[img.OperatingSystem()].Get(chainID) - if err != nil { -+ logrus.Errorf("layer does not exist, not restoring image %v, %v, %s", dgst, chainID, img.OperatingSystem()) -+ // If the layer doesn't exist, return nil to ignore this image. - if err == layer.ErrLayerDoesNotExist { -- logrus.Errorf("layer does not exist, not restoring image %v, %v, %s", dgst, chainID, img.OperatingSystem()) - return nil - } - return err -diff --git a/components/engine/layer/layer_store.go b/components/engine/layer/layer_store.go -index 6a568e9d9b..351f787b87 100644 ---- a/components/engine/layer/layer_store.go -+++ b/components/engine/layer/layer_store.go -@@ -105,7 +105,7 @@ func newStoreFromGraphDriver(root string, driver graphdriver.Driver, os string) - for _, id := range ids { - l, err := ls.loadLayer(id) - if err != nil { -- logrus.Debugf("Failed to load layer %s: %s", id, err) -+ logrus.Warnf("Failed to load layer %s: %s", id, err) - continue - } - if l.parent != nil { -@@ -126,11 +126,17 @@ func (ls *layerStore) Driver() graphdriver.Driver { - return ls.driver - } - --func (ls *layerStore) loadLayer(layer ChainID) (*roLayer, error) { -+func (ls *layerStore) loadLayer(layer ChainID) (l *roLayer, err error) { - cl, ok := ls.layerMap[layer] - if ok { - return cl, nil - } -+ defer func() { -+ // If failed to load the layer, remove the layer metadata. -+ if err != nil { -+ ls.store.Remove(layer) -+ } -+ }() - - diff, err := ls.store.GetDiffID(layer) - if err != nil { -@@ -147,6 +153,11 @@ func (ls *layerStore) loadLayer(layer ChainID) (*roLayer, error) { - return nil, fmt.Errorf("failed to get cache id for %s: %s", layer, err) - } - -+ // Check whether the layer exists in graphdriver here. -+ if exist := ls.driver.Exists(cacheID); !exist { -+ return nil, fmt.Errorf("cacheID %s for layer %s does not exists in graphdriver", cacheID, layer) -+ } -+ - parent, err := ls.store.GetParent(layer) - if err != nil { - return nil, fmt.Errorf("failed to get parent for %s: %s", layer, err) --- -2.17.1 - diff --git a/patch/0035-restart-reject-to-restart-container-when-remo.patch b/patch/0035-restart-reject-to-restart-container-when-remo.patch deleted file mode 100644 index 5caad6e..0000000 --- a/patch/0035-restart-reject-to-restart-container-when-remo.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 2e0fda9de03efe4f399a35c52cac2444b5518709 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 9 Jan 2019 16:43:39 +0800 -Subject: [PATCH 035/111] restart: reject to restart container when - removing it - -reason: cherry-pick commits to docker-18.09 - -concurrence of restart and remove a container may cause -that container info is still saved in memdb while container is actually -already removed. - -cherry-pick from 1.11.2: f7eeafa -Conflicts: - daemon/restart.go - -Change-Id: Ic9be384c908f49697c87f6b51ffcb1968f38d6cc -Signed-off-by: liruilin4 -Signed-off-by: lixiang172 ---- - components/engine/daemon/restart.go | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/components/engine/daemon/restart.go b/components/engine/daemon/restart.go -index bae665f76b..2c441de873 100644 ---- a/components/engine/daemon/restart.go -+++ b/components/engine/daemon/restart.go -@@ -55,6 +55,11 @@ func (daemon *Daemon) containerRestart(container *container.Container, seconds i - container.HostConfig.AutoRemove = autoRemove - // containerStop will write HostConfig to disk, we shall restore AutoRemove - // in disk too -+ // if rm running concurrently, the container may be already removed now. we should not -+ // save it to disk -+ if container.RemovalInProgress || container.Dead { -+ return fmt.Errorf("can't restart a container which is dead or marked for removal") -+ } - if toDiskErr := daemon.checkpointAndSave(container); toDiskErr != nil { - logrus.Errorf("Write container to disk error: %v", toDiskErr) - } --- -2.17.1 - diff --git a/patch/0036-restart-do-not-reset-container-restartCount-o.patch b/patch/0036-restart-do-not-reset-container-restartCount-o.patch deleted file mode 100644 index 5c047ab..0000000 --- a/patch/0036-restart-do-not-reset-container-restartCount-o.patch +++ /dev/null @@ -1,41 +0,0 @@ -From af5045eb5d9cc84afeace447e2bf3e1571866f4d Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 9 Jan 2019 16:52:39 +0800 -Subject: [PATCH 036/111] restart: do not reset container restartCount - on boot - -reason: cherry-pick commits to docker-18.09 - -when daemon restart, container's RestartCount will be reseted to 0 - this is cherry-picked from docker - commit:3bffccc719bf8237ce78af8b88aaa7757f43795a - Signed-off-by: dengguangxing - -cherry-pick from 1.11.2: d5292e3 - -Conflicts: - daemon/daemon.go - -Change-Id: I2276e9d075b593b74e4b17c0f8e48a2dec3e6f4c -Signed-off-by: xueshaojia -Signed-off-by: lixiang172 ---- - components/engine/daemon/daemon.go | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 4546587369..a058688dd3 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -532,7 +532,7 @@ func (daemon *Daemon) restore() error { - - // Make sure networks are available before starting - daemon.waitForNetworks(c) -- if err := daemon.containerStart(c, "", "", true); err != nil { -+ if err := daemon.containerStart(c, "", "", false); err != nil { - logrus.Errorf("Failed to start container %s: %s", c.ID, err) - } - close(chNotify) --- -2.17.1 - diff --git a/patch/0037-config-Add-liver-restore-to-OPTIION-to-enable.patch b/patch/0037-config-Add-liver-restore-to-OPTIION-to-enable.patch deleted file mode 100644 index de43188..0000000 --- a/patch/0037-config-Add-liver-restore-to-OPTIION-to-enable.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 5f82c47f5f08655e325610a9430a4e891c71857a Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 3 Jan 2019 13:58:17 +0800 -Subject: [PATCH 037/111] config: Add --liver-restore to OPTIION to - enable live restore by default - -reason: cherry-pick commits to docker-18.09 - -this commit copy latest file from docker-1.11.2 - -cherry-pick from -c9846ccea8 | * Add --liver-restore to OPTIION to enable live restore by -default - -Change-Id: I9c52a81d1bb06f2abb090bbd048cbf2dbc44956a -Signed-off-by: Lei Jitang -Signed-off-by: jingrui ---- - .../init/sysvinit-redhat/docker.sysconfig | 19 ++++++++++++++----- - 1 file changed, 14 insertions(+), 5 deletions(-) - -diff --git a/components/engine/contrib/init/sysvinit-redhat/docker.sysconfig b/components/engine/contrib/init/sysvinit-redhat/docker.sysconfig -index 0864b3d77f..234acad1dd 100644 ---- a/components/engine/contrib/init/sysvinit-redhat/docker.sysconfig -+++ b/components/engine/contrib/init/sysvinit-redhat/docker.sysconfig -@@ -1,7 +1,16 @@ - # /etc/sysconfig/docker --# --# Other arguments to pass to the docker daemon process --# These will be parsed by the sysv initscript and appended --# to the arguments list passed to docker daemon - --other_args="" -+# Modify these options if you want to change the way the docker daemon runs -+OPTIONS='--live-restore' -+ -+DOCKER_CERT_PATH=/etc/docker -+ -+# If you have a registry secured with https but do not have proper certs -+# distributed, you can tell docker to not look for full authorization by -+# adding the registry to the INSECURE_REGISTRY line and uncommenting it. -+# INSECURE_REGISTRY='--insecure-registry' -+ -+# Location used for temporary files, such as those created by -+# docker load and build operations. Default is /var/lib/docker/tmp -+# Can be overridden by setting the following environment variable. -+# DOCKER_TMPDIR=/var/tmp --- -2.17.1 - diff --git a/patch/0038-devmapper-devicemapper-ignore-error-when-remo.patch b/patch/0038-devmapper-devicemapper-ignore-error-when-remo.patch deleted file mode 100644 index f26b15e..0000000 --- a/patch/0038-devmapper-devicemapper-ignore-error-when-remo.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 42da0fd120db6f5b34c523212b54b88e8837efa6 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 3 Jan 2019 14:09:59 +0800 -Subject: [PATCH 038/111] devmapper: devicemapper: ignore error when - remove a device which does not exist - -reason: cherry-pick commits to docker-18.09 - -cherry-pick from -e91268fda7 | * devicemapper: ignore error when remove a device which -does not exist - -Conflicts: - daemon/graphdriver/devmapper/deviceset.go - pkg/devicemapper/devmapper.go - -Change-Id: Ia1d33d78e4d7000c6e4bd54ec203800a0234cae5 -Signed-off-by: Liu Hua -Signed-off-by: jingrui ---- - .../engine/daemon/graphdriver/devmapper/deviceset.go | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/components/engine/daemon/graphdriver/devmapper/deviceset.go b/components/engine/daemon/graphdriver/devmapper/deviceset.go -index 0675b2eacd..be48d92e8d 100644 ---- a/components/engine/daemon/graphdriver/devmapper/deviceset.go -+++ b/components/engine/daemon/graphdriver/devmapper/deviceset.go -@@ -2137,6 +2137,13 @@ func (devices *DeviceSet) deactivateDeviceMode(info *devInfo, deferredRemove boo - - if deferredRemove { - err = devicemapper.RemoveDeviceDeferred(info.Name()) -+ if err != nil { -+ if err == devicemapper.ErrEnxio { -+ logrus.Warnf("devmapper: device %s has gone", info.Name()) -+ return nil -+ } -+ return err -+ } - } else { - err = devices.removeDevice(info.Name()) - } --- -2.17.1 - diff --git a/patch/0039-restart-Remove-redundant-Mounts-when-start-do.patch b/patch/0039-restart-Remove-redundant-Mounts-when-start-do.patch deleted file mode 100644 index f5d27e9..0000000 --- a/patch/0039-restart-Remove-redundant-Mounts-when-start-do.patch +++ /dev/null @@ -1,361 +0,0 @@ -From 49a3cd1ceb6956bd7787135a7938543d64d30638 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 3 Jan 2019 14:02:32 +0800 -Subject: [PATCH 039/111] restart: -- Remove redundant Mounts when - start docker daemon - -reason: cherry-pick commits to docker-18.09 - -merge from -b192ce147d * Remove redundant Mounts when start docker daemon -8b031c9488 * devicemapper: remove redundant mountpoint when docker -restart -9a3c14633e * Revert "devicemapper: remove redundant mountpoint when -docker restart" -7bbda93537 * devicemapper: remove redundant mountpoint when docker -restart -0be4e475d7 * remove redundant containers/xxx/shm mountpoint -d4adbe2bf7 * Remove redundant overlay2 mountpoints - ---- -Remove redundant Mounts when start docker daemon - - -Signed-off-by: yangshukui ---- -devicemapper: remove redundant mountpoint when docker restart - -Modify the regexp patterns in `getIdPatterns` in order to match -`/var/lib/docker/devicemapper/mnt/xxx-init`. - -Fix #254 - -Signed-off-by: Yuanhong Peng ---- -Revert "devicemapper: remove redundant mountpoint when docker restart" - -With this commit, daemon will restart with error: -``` -level=error msg="devmapper: Error unmounting device -0019325b1b09c75da1c9c97dcffdc024498d318b2c148e4ebe67b1cda4ac446e: -devmapper: Unknown device -0019325b1b09c75da1c9c97dcffdc024498d318b2c148e4ebe67b1cda4ac446e" -``` -Here, the redundant device is `xxx-init` not `xxx`. - -This reverts commit 8b031c9488236a9a808be7aed4cce69786dec010. - -Signed-off-by: Yuanhong Peng ---- -devicemapper: remove redundant mountpoint when docker restart - -Modify the regexp patterns in `getIdPatterns` in order to match -`/var/lib/docker/devicemapper/mnt/xxx-init`. - -Fix #254 - -Signed-off-by: Yuanhong Peng ---- -remove redundant containers/xxx/shm mountpoint - -fix problems caused by killing docker daemon when running a container -once restarted, docker ps shows container in created status but failed -to rm it with `container/xxx/shm device or resource busy` - - -Signed-off-by: Deng Guangxing ---- -Remove redundant overlay2 mountpoints - -Modify the regexp patterns in `getIdPatterns` in order to match -/var/lib/docker/overlay2/xxx/merged. - -Signed-off-by: Yuanhong Peng ---- -Signed-off-by: jingrui - -Change-Id: I4859d9cca731477fc64be6772d8c4b89a000f1b5 ---- - components/engine/daemon/daemon.go | 6 + - components/engine/daemon/daemon_unix.go | 132 ++++++++++++++++++ - components/engine/daemon/daemon_unix_test.go | 29 ++++ - components/engine/daemon/daemon_windows.go | 4 + - components/engine/daemon/images/service.go | 4 + - .../engine/distribution/xfer/download_test.go | 4 + - components/engine/layer/layer.go | 1 + - components/engine/layer/layer_store.go | 4 + - 8 files changed, 184 insertions(+) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index a058688dd3..b207709f7c 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -486,6 +486,12 @@ func (daemon *Daemon) restore() error { - } - wg.Wait() - -+ err = daemon.removeRedundantMounts(containers) -+ if err != nil { -+ // just print error info -+ logrus.Errorf("removeRedundantMounts failed %v", err) -+ } -+ - containerIDs := make(map[string]struct{}) - for cid, _ := range containers { - containerIDs[cid] = struct{}{} -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index 8ffdd0009a..d4a32a0b25 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -10,6 +10,7 @@ import ( - "net" - "os" - "path/filepath" -+ "regexp" - "runtime" - "runtime/debug" - "strconv" -@@ -1587,3 +1588,134 @@ func (daemon *Daemon) setupSeccompProfile() error { - } - return nil - } -+ -+func getIdPatterns(id string) (regexps []*regexp.Regexp) { -+ var patterns []string -+ if id == "" { -+ id = "(?P[0-9a-f]{64})" -+ } -+ patterns = append(patterns, "aufs/mnt/"+id+"(-init)?"+"$", "overlay/"+id+"(-init)?"+"/merged$", "overlay2/"+id+"(-init)?"+"/merged$", "zfs/graph/"+id+"(-init)?"+"$", "devicemapper/mnt/"+id+"(-init)?"+"$") -+ for _, p := range patterns { -+ r, err := regexp.Compile(p) -+ if err == nil { -+ regexps = append(regexps, r) -+ } -+ } -+ return -+} -+ -+func getContainerMountId(path string) (bool, string) { -+ regs := getIdPatterns("") -+ for _, reg := range regs { -+ ret := reg.FindStringSubmatch(path) -+ if len(ret) == 3 { -+ if ret[2] == "" { -+ return false, ret[1] -+ } else { -+ return true, ret[1] -+ } -+ } -+ } -+ return false, "" -+} -+ -+func isContainerMount(path string) (bool, string) { -+ var regs []*regexp.Regexp -+ var patterns []string -+ var id = "(?P[0-9a-f]{64})" -+ -+ // TODO: fill in patterns with other mounts info -+ patterns = append(patterns, "containers/"+id+"/shm$") -+ for _, p := range patterns { -+ r, err := regexp.Compile(p) -+ if err == nil { -+ regs = append(regs, r) -+ } -+ } -+ -+ for _, reg := range regs { -+ ret := reg.FindStringSubmatch(path) -+ if len(ret) == 2 { -+ return true, ret[1] -+ } -+ } -+ return false, "" -+} -+ -+func (daemon *Daemon) removeRedundantMounts(containers map[string]*container.Container) error { -+ var ( -+ isShmMount, isInitdev bool -+ id string -+ redundantMounts = map[string]bool{} -+ ) -+ -+ // Get redundant Mounts -+ f, err := os.Open("/proc/self/mountinfo") -+ if err != nil { -+ return err -+ } -+ defer f.Close() -+ -+ activeContainers := map[string]string{} -+ for _, c := range containers { -+ if c.IsRunning() && !c.IsRestarting() { -+ activeContainers[c.ID] = c.ID -+ if mountid, err := daemon.imageService.GetLayerMountID(c.ID, c.OS); err == nil { -+ activeContainers[mountid] = c.ID -+ logrus.Debugf("removeRedundantMounts, mountid %s, containerID %s\n", mountid, c.ID) -+ } -+ } -+ } -+ root := filepath.Join(daemon.root, daemon.imageService.GraphDriverForOS(runtime.GOOS)) -+ scanner := bufio.NewScanner(f) -+ for scanner.Scan() { -+ text := scanner.Text() -+ fields := strings.Split(text, " ") -+ if len(fields) < 5 { -+ return fmt.Errorf("%s", "/proc/self/mountinfo format err") -+ } -+ path := fields[4] -+ if !strings.HasPrefix(path, daemon.root) || path == root { -+ continue -+ } -+ -+ isShmMount, id = isContainerMount(path) -+ if !isShmMount { -+ isInitdev, id = getContainerMountId(path) -+ } -+ if id == "" { -+ continue -+ } -+ -+ if _, ok := activeContainers[id]; !ok { -+ if isShmMount { -+ redundantMounts[path] = true -+ } else { -+ if isInitdev { -+ id = fmt.Sprintf("%s-init", id) -+ } -+ redundantMounts[id] = false -+ } -+ } -+ } -+ if err := scanner.Err(); err != nil { -+ return err -+ } -+ -+ // Remove redundant Mounts -+ for path, shm := range redundantMounts { -+ var ( -+ err error -+ ) -+ logrus.Debugf("Umount legacy mountpoint [%s]", path) -+ if shm { -+ err = mount.Unmount(path) -+ } else { -+ err = daemon.imageService.DriverPut(runtime.GOOS, path) -+ } -+ if err != nil { -+ logrus.Debugf("Umount legacy mountpoint: %s failed with %s", path, err) -+ } -+ } -+ return err -+} -diff --git a/components/engine/daemon/daemon_unix_test.go b/components/engine/daemon/daemon_unix_test.go -index 36c6030988..d9bba54a93 100644 ---- a/components/engine/daemon/daemon_unix_test.go -+++ b/components/engine/daemon/daemon_unix_test.go -@@ -266,3 +266,32 @@ func TestNetworkOptions(t *testing.T) { - t.Fatal("Expected networkOptions error, got nil") - } - } -+ -+func TestGetContainerMountId(t *testing.T) { -+ id := "56e143922c405419a38b23bfbccc92284f35525e3f2ad7011ea904501ccd1219" -+ -+ id1 := getContainerMountId("/var/lib/docker/aufs/mnt/" + id) -+ if id1 != id { -+ t.Fatalf("Expected container mount id [%s], but got [%s]", id, id1) -+ } -+ -+ id1 = getContainerMountId("/var/lib/docker/devicemapper/mnt/" + id) -+ if id1 != id { -+ t.Fatalf("Expected container mount id [%s], but got [%s]", id, id1) -+ } -+ -+ id1 = getContainerMountId("/var/lib/docker/overlay/" + id + "/merged") -+ if id1 != id { -+ t.Fatalf("Expected container mount id [%s], but got [%s]", id, id1) -+ } -+ -+ id1 = getContainerMountId("/var/lib/docker/zfs/graph/" + id) -+ if id1 != id { -+ t.Fatalf("Expected container mount id [%s], but got [%s]", id, id1) -+ } -+ -+ id1 = getContainerMountId("/var/lib/docker/devicemapper_err/mnt" + id) -+ if id1 != "" { -+ t.Fatalf("Expected a empty container mount id, but got [%s]", id1) -+ } -+} -diff --git a/components/engine/daemon/daemon_windows.go b/components/engine/daemon/daemon_windows.go -index 4812236bc2..9d895b3dfa 100644 ---- a/components/engine/daemon/daemon_windows.go -+++ b/components/engine/daemon/daemon_windows.go -@@ -657,3 +657,7 @@ func (daemon *Daemon) initRuntimes(_ map[string]types.Runtime) error { - - func setupResolvConf(config *config.Config) { - } -+ -+func (daemon *Daemon) removeRedundantMounts(containers map[string]*container.Container) error { -+ return nil -+} -diff --git a/components/engine/daemon/images/service.go b/components/engine/daemon/images/service.go -index 8d187e2603..e43a4c6651 100644 ---- a/components/engine/daemon/images/service.go -+++ b/components/engine/daemon/images/service.go -@@ -193,6 +193,10 @@ func (i *ImageService) ReleaseLayer(rwlayer layer.RWLayer, containerOS string) e - return nil - } - -+func (i *ImageService) DriverPut(os string, path string) error { -+ return i.layerStores[os].DriverPut(path) -+} -+ - // LayerDiskUsage returns the number of bytes used by layer stores - // called from disk_usage.go - func (i *ImageService) LayerDiskUsage(ctx context.Context) (int64, error) { -diff --git a/components/engine/distribution/xfer/download_test.go b/components/engine/distribution/xfer/download_test.go -index 91153591ed..c4c4aefba9 100644 ---- a/components/engine/distribution/xfer/download_test.go -+++ b/components/engine/distribution/xfer/download_test.go -@@ -146,6 +146,10 @@ func (ls *mockLayerStore) Cleanup() error { - return nil - } - -+func (ls *mockLayerStore) DriverPut(id string) error { -+ return nil -+} -+ - func (ls *mockLayerStore) DriverStatus() [][2]string { - return [][2]string{} - } -diff --git a/components/engine/layer/layer.go b/components/engine/layer/layer.go -index 425006854d..cb13c98d0b 100644 ---- a/components/engine/layer/layer.go -+++ b/components/engine/layer/layer.go -@@ -191,6 +191,7 @@ type Store interface { - ReleaseRWLayer(RWLayer) ([]Metadata, error) - - Cleanup() error -+ DriverPut(id string) error - DriverStatus() [][2]string - DriverName() string - CleanupRedundant(map[string]struct{}) error -diff --git a/components/engine/layer/layer_store.go b/components/engine/layer/layer_store.go -index 351f787b87..5decb0bdce 100644 ---- a/components/engine/layer/layer_store.go -+++ b/components/engine/layer/layer_store.go -@@ -807,6 +807,10 @@ func (ls *layerStore) Cleanup() error { - return ls.driver.Cleanup() - } - -+func (ls *layerStore) DriverPut(id string) error { -+ return ls.driver.Put(id) -+} -+ - func (ls *layerStore) DriverStatus() [][2]string { - return ls.driver.Status() - } --- -2.17.1 - diff --git a/patch/0040-devmapper-devicemapper-add-API-GetDeviceList.patch b/patch/0040-devmapper-devicemapper-add-API-GetDeviceList.patch deleted file mode 100644 index b4a744c..0000000 --- a/patch/0040-devmapper-devicemapper-add-API-GetDeviceList.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 9df99e9c4b27a3ccfae5f9b5b285784aeaaf1ac9 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Mon, 7 Jan 2019 13:36:04 +0800 -Subject: [PATCH 040/111] devmapper: devicemapper: add API - GetDeviceList - -reason: cherry-pick commits to docker-18.09 - -cherry-pick from 58fa445402 * devicemapper: add API GetDeviceList - -Change-Id: Ia52611b75f12179bbe2e718e1b8575f0825d5dd7 -Signed-off-by: Wang Long -Signed-off-by: jingrui ---- - .../engine/pkg/devicemapper/devmapper.go | 21 ++++++ - .../pkg/devicemapper/devmapper_wrapper.go | 67 +++++++++++++++++++ - 2 files changed, 88 insertions(+) - -diff --git a/components/engine/pkg/devicemapper/devmapper.go b/components/engine/pkg/devicemapper/devmapper.go -index b384a27f8f..06ddc3e96b 100644 ---- a/components/engine/pkg/devicemapper/devmapper.go -+++ b/components/engine/pkg/devicemapper/devmapper.go -@@ -55,6 +55,7 @@ var ( - ErrTaskGetDeps = errors.New("dm_task_get_deps failed") - ErrTaskGetInfo = errors.New("dm_task_get_info failed") - ErrTaskGetDriverVersion = errors.New("dm_task_get_driver_version failed") -+ ErrTaskGetNames = errors.New("dm_task_get_names failed") - ErrTaskDeferredRemove = errors.New("dm_task_deferred_remove failed") - ErrTaskSetCookie = errors.New("dm_task_set_cookie failed") - ErrNilCookie = errors.New("cookie ptr can't be nil") -@@ -241,6 +242,14 @@ func (t *Task) getInfoWithDeferred() (*Info, error) { - return info, nil - } - -+func (t *Task) getDeviceList() ([]string, error) { -+ res := DmTaskGetNames(t.unmanaged) -+ if res == nil { -+ return nil, ErrTaskGetNames -+ } -+ return res, nil -+} -+ - func (t *Task) getDriverVersion() (string, error) { - res := DmTaskGetDriverVersion(t.unmanaged) - if res == "" { -@@ -569,6 +578,18 @@ func GetInfoWithDeferred(name string) (*Info, error) { - return task.getInfoWithDeferred() - } - -+// GetDevices get all device name -+func GetDeviceList() ([]string, error) { -+ task := TaskCreate(deviceList) -+ if task == nil { -+ return nil, fmt.Errorf("devicemapper: Can't create deviceList task") -+ } -+ if err := task.run(); err != nil { -+ return nil, err -+ } -+ return task.getDeviceList() -+} -+ - // GetDriverVersion is the programmatic example of "dmsetup version". - // It outputs version information of the driver. - func GetDriverVersion() (string, error) { -diff --git a/components/engine/pkg/devicemapper/devmapper_wrapper.go b/components/engine/pkg/devicemapper/devmapper_wrapper.go -index 77cd674a09..3b00a3b54b 100644 ---- a/components/engine/pkg/devicemapper/devmapper_wrapper.go -+++ b/components/engine/pkg/devicemapper/devmapper_wrapper.go -@@ -6,6 +6,9 @@ package devicemapper // import "github.com/docker/docker/pkg/devicemapper" - #define _GNU_SOURCE - #include - #include // FIXME: present only for BLKGETSIZE64, maybe we can remove it? -+#include -+#include -+ - - // FIXME: Can't we find a way to do the logging in pure Go? - extern void DevmapperLogCallback(int level, char *file, int line, int dm_errno_or_class, char *str); -@@ -32,6 +35,51 @@ static void log_with_errno_init() - { - dm_log_with_errno_init(log_cb); - } -+ -+// FIXME: how to use dm_task_get_names directly -+static char **local_dm_task_get_names(struct dm_task *dmt, unsigned int *size) { -+ struct dm_names *ns, *ns1; -+ unsigned next = 0; -+ char **result; -+ int i = 0; -+ -+ if (!(ns = dm_task_get_names(dmt))) -+ return NULL; -+ -+ // No devices found -+ if (!ns->dev) -+ return NULL; -+ -+ // calucate the total devices -+ ns1 = ns; -+ *size = 0; -+ do { -+ ns1 = (struct dm_names *)((char *) ns1 + next); -+ (*size)++; -+ next = ns1->next; -+ } while (next); -+ -+ result = malloc(sizeof(char *)* (*size)); -+ if (!result) -+ return NULL; -+ -+ next = 0; -+ do { -+ ns = (struct dm_names *)((char *) ns + next); -+ result[i++] = strdup(ns->name); -+ next = ns->next; -+ } while (next); -+ -+ return result; -+} -+ -+void free_devices_names(char **names, unsigned int size) { -+ int i; -+ -+ for (i = 0; i < size; i++) -+ free(names[i]); -+ free(names); -+} - */ - import "C" - -@@ -69,6 +117,7 @@ var ( - DmTaskGetDeps = dmTaskGetDepsFct - DmTaskGetInfo = dmTaskGetInfoFct - DmTaskGetDriverVersion = dmTaskGetDriverVersionFct -+ DmTaskGetNames = dmTaskGetNamesFct - DmTaskRun = dmTaskRunFct - DmTaskSetAddNode = dmTaskSetAddNodeFct - DmTaskSetCookie = dmTaskSetCookieFct -@@ -190,6 +239,24 @@ func dmTaskGetInfoFct(task *cdmTask, info *Info) int { - return int(C.dm_task_get_info((*C.struct_dm_task)(task), &Cinfo)) - } - -+func dmTaskGetNamesFct(task *cdmTask) []string { -+ var res []string -+ var names []*C.char -+ len := C.uint(0) -+ Cnames := C.local_dm_task_get_names((*C.struct_dm_task)(task), &len) -+ defer C.free_devices_names(Cnames, len) -+ -+ hdr := (*reflect.SliceHeader)(unsafe.Pointer(&names)) -+ hdr.Cap = int(len) -+ hdr.Len = int(len) -+ hdr.Data = uintptr(unsafe.Pointer(Cnames)) -+ -+ for _, name := range names { -+ res = append(res, C.GoString(name)) -+ } -+ return res -+} -+ - func dmTaskGetDriverVersionFct(task *cdmTask) string { - buffer := C.malloc(128) - defer C.free(buffer) --- -2.17.1 - diff --git a/patch/0041-devmapper-devmapper-remove-broken-device-when.patch b/patch/0041-devmapper-devmapper-remove-broken-device-when.patch deleted file mode 100644 index fe40752..0000000 --- a/patch/0041-devmapper-devmapper-remove-broken-device-when.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 544b5be235f9a34a5c75a936549bf6d6f2280339 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 3 Jan 2019 15:22:26 +0800 -Subject: [PATCH 041/111] devmapper: devmapper: remove broken device - when start daemon - -reason: cherry-pick commits to docker-18.09 - -cherry-pick from -6104c8e237 | * devmapper: remove broken device when start daemon - -When use `kill -9 docker-daemon-pid` to stop docker, It may casue that -the status of devicemapper devices inconsisitent. eg, we can see the -device info use `dmsetup status` command, but the device does not exist -in `/dev/mapper` directory. - -At next time docker start, it will start failed or load container -failed. - -This patch add a check when docker start in `initDevmapper` function. -First, we find all devmapper devices in the system. Then If the device -name has a prefix with `docker-{major}:{minor}-{inode}` and the length -is equal to zero, we use `devicemapper.RemoveDevice` remove the device. - - -Change-Id: I7eccf4e9539751d615b953abf94951b7e94153d1 -Signed-off-by: Wang Long -Signed-off-by: jingrui ---- - .../daemon/graphdriver/devmapper/deviceset.go | 23 +++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/components/engine/daemon/graphdriver/devmapper/deviceset.go b/components/engine/daemon/graphdriver/devmapper/deviceset.go -index be48d92e8d..b3e142e2ba 100644 ---- a/components/engine/daemon/graphdriver/devmapper/deviceset.go -+++ b/components/engine/daemon/graphdriver/devmapper/deviceset.go -@@ -1732,6 +1732,29 @@ func (devices *DeviceSet) initDevmapper(doInit bool) (retErr error) { - devices.devicePrefix = fmt.Sprintf("docker-%d:%d-%d", major(st.Dev), minor(st.Dev), st.Ino) - logger.Debugf("Generated prefix: %s", devices.devicePrefix) - -+ deviceNames, err := devicemapper.GetDeviceList() -+ if err != nil { -+ logrus.Debugf("devmapper: Failed to get device list: %s", err) -+ } -+ -+ for _, name := range deviceNames { -+ if !strings.HasPrefix(name, devices.devicePrefix) { -+ continue -+ } -+ _, length, _, _, err := devicemapper.GetStatus(name) -+ if err != nil { -+ logrus.Warnf("devmapper: get device status(%s): %s", name, err) -+ continue -+ } -+ // remove broken device -+ if length == 0 { -+ if err := devicemapper.RemoveDevice(name); err != nil { -+ logrus.Warnf("devmapper: remove broken device(%s): %s", name, err) -+ } -+ logrus.Debugf("devmapper: remove broken device: %s", name) -+ } -+ } -+ - // Check for the existence of the thin-pool device - poolExists, err := devices.thinPoolExists(devices.getPoolName()) - if err != nil { --- -2.17.1 - diff --git a/patch/0042-oci-Cannot-join-own-pid-ipc-namespace.patch b/patch/0042-oci-Cannot-join-own-pid-ipc-namespace.patch deleted file mode 100644 index 4e4647a..0000000 --- a/patch/0042-oci-Cannot-join-own-pid-ipc-namespace.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 50c51324293064e12e99da9dfbb3554ab1255f51 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 3 Jan 2019 15:30:42 +0800 -Subject: [PATCH 042/111] oci: Cannot join own pid/ipc namespace - -reason: cherry-pick commits to docker-18.09 - -Change-Id: I34a0d97a4196d509d80d20f262f3fbac555e0745 -Signed-off-by: Yuanhong Peng -Signed-off-by: jingrui ---- - .../daemon/container_operations_unix.go | 20 +++++++++----- - components/engine/daemon/oci_linux.go | 2 +- - .../integration-cli/docker_cli_run_test.go | 27 +++++++++++++++++++ - 3 files changed, 42 insertions(+), 7 deletions(-) - -diff --git a/components/engine/daemon/container_operations_unix.go b/components/engine/daemon/container_operations_unix.go -index 9953c7f3fd..2cc2b2e3cd 100644 ---- a/components/engine/daemon/container_operations_unix.go -+++ b/components/engine/daemon/container_operations_unix.go -@@ -58,13 +58,17 @@ func (daemon *Daemon) setupLinkedContainers(container *container.Container) ([]s - return env, nil - } - --func (daemon *Daemon) getIpcContainer(id string) (*container.Container, error) { -- errMsg := "can't join IPC of container " + id -+func (daemon *Daemon) getIpcContainer(cc *container.Container) (*container.Container, error) { -+ containerID := cc.HostConfig.IpcMode.Container() -+ errMsg := "can't join IPC of container " + containerID - // Check the container exists -- container, err := daemon.GetContainer(id) -+ container, err := daemon.GetContainer(containerID) - if err != nil { - return nil, errors.Wrap(err, errMsg) - } -+ if container.ID == cc.ID { -+ return nil, fmt.Errorf("cannot join own ipc namespace") -+ } - // Check the container is running and not restarting - if err := daemon.checkContainer(container, containerIsRunning, containerIsNotRestarting); err != nil { - return nil, errors.Wrap(err, errMsg) -@@ -81,12 +85,16 @@ func (daemon *Daemon) getIpcContainer(id string) (*container.Container, error) { - return container, nil - } - --func (daemon *Daemon) getPidContainer(container *container.Container) (*container.Container, error) { -- containerID := container.HostConfig.PidMode.Container() -+func (daemon *Daemon) getPidContainer(cc *container.Container) (*container.Container, error) { -+ containerID := cc.HostConfig.PidMode.Container() - container, err := daemon.GetContainer(containerID) - if err != nil { - return nil, errors.Wrapf(err, "cannot join PID of a non running container: %s", containerID) - } -+ if container.ID == cc.ID { -+ return nil, fmt.Errorf("cannot join own pid namespace") -+ } -+ - return container, daemon.checkContainer(container, containerIsRunning, containerIsNotRestarting) - } - -@@ -109,7 +117,7 @@ func (daemon *Daemon) setupIpcDirs(c *container.Container) error { - - switch { - case ipcMode.IsContainer(): -- ic, err := daemon.getIpcContainer(ipcMode.Container()) -+ ic, err := daemon.getIpcContainer(c) - if err != nil { - return err - } -diff --git a/components/engine/daemon/oci_linux.go b/components/engine/daemon/oci_linux.go -index 884739c07e..f5270bd545 100644 ---- a/components/engine/daemon/oci_linux.go -+++ b/components/engine/daemon/oci_linux.go -@@ -256,7 +256,7 @@ func setNamespaces(daemon *Daemon, s *specs.Spec, c *container.Container) error - switch { - case ipcMode.IsContainer(): - ns := specs.LinuxNamespace{Type: "ipc"} -- ic, err := daemon.getIpcContainer(ipcMode.Container()) -+ ic, err := daemon.getIpcContainer(c) - if err != nil { - return err - } -diff --git a/components/engine/integration-cli/docker_cli_run_test.go b/components/engine/integration-cli/docker_cli_run_test.go -index 4f55c05aeb..4a137c6159 100644 ---- a/components/engine/integration-cli/docker_cli_run_test.go -+++ b/components/engine/integration-cli/docker_cli_run_test.go -@@ -2323,6 +2323,15 @@ func (s *DockerSuite) TestRunModeIpcContainerNotExists(c *check.C) { - } - } - -+func (s *DockerSuite) TestJoinOwnIpcNamespace(c *check.C) { -+ // Not applicable on Windows as uses Unix-specific capabilities -+ testRequires(c, DaemonIsLinux, NotUserNamespace) -+ _, _, err := dockerCmdWithError("run", "-d", "--name", "testipc", "--ipc", "container:testipc", "busybox", "top") -+ if err == nil { -+ c.Fatalf("Join own ipc namespace is not permitted") -+ } -+} -+ - func (s *DockerSuite) TestRunModeIpcContainerNotRunning(c *check.C) { - // Not applicable on Windows as uses Unix-specific capabilities - testRequires(c, SameHostDaemon, DaemonIsLinux) -@@ -2383,6 +2392,15 @@ func (s *DockerSuite) TestRunModePIDContainerNotRunning(c *check.C) { - } - } - -+func (s *DockerSuite) TestJoinOwnPidNamespace(c *check.C) { -+ // Not applicable on Windows as uses Unix-specific capabilities -+ testRequires(c, DaemonIsLinux) -+ _, _, err := dockerCmdWithError("run", "-d", "--name", "testpid", "--pid", "container:testpid", "busybox", "top") -+ if err == nil { -+ c.Fatalf("Join own pid namespace is not permitted") -+ } -+} -+ - func (s *DockerSuite) TestRunMountShmMqueueFromHost(c *check.C) { - // Not applicable on Windows as uses Unix-specific capabilities - testRequires(c, SameHostDaemon, DaemonIsLinux, NotUserNamespace) -@@ -2621,6 +2639,15 @@ func (s *DockerSuite) TestRunNetContainerWhichHost(c *check.C) { - } - } - -+func (s *DockerSuite) TestJoinOwnNetNamespace(c *check.C) { -+ // Not applicable on Windows as uses Unix-specific capabilities -+ testRequires(c, DaemonIsLinux, NotUserNamespace) -+ _, _, err := dockerCmdWithError("run", "-d", "--name", "testnet", "--net", "container:testnet", "busybox", "top") -+ if err == nil { -+ c.Fatalf("Join own net namespace is not permitted") -+ } -+} -+ - func (s *DockerSuite) TestRunAllowPortRangeThroughPublish(c *check.C) { - // TODO Windows. This may be possible to enable in the future. However, - // Windows does not currently support --expose, or populate the network --- -2.17.1 - diff --git a/patch/0043-docker-Make-sure-the-pid-exist-in-pidfile-is-.patch b/patch/0043-docker-Make-sure-the-pid-exist-in-pidfile-is-.patch deleted file mode 100644 index d449664..0000000 --- a/patch/0043-docker-Make-sure-the-pid-exist-in-pidfile-is-.patch +++ /dev/null @@ -1,81 +0,0 @@ -From f70a2648621ab1463299eabecda8e8c7584831c3 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 3 Jan 2019 16:01:36 +0800 -Subject: [PATCH 043/111] docker: Make sure the pid exist in pidfile - is docker - -reason: cherry-pick commits to docker-18.09. - -cherry-pick from -b4714e3321 | * Make sure the pid exist in pidfile is docker - - -Because of the recycling of used PIDs policy in kernel, -it could be possible that the process died with pidfile existing -and when the process boot next time, the pid in pidfile has been assigned -to another process, this would make the process can't be boot again without -removing the pidfile manually. - -Change-Id: I237566682716733174900cd4dc76ce74ff9f4195 -Signed-off-by: Lei Jitang -Signed-off-by: jingrui ---- - components/engine/pkg/pidfile/pidfile.go | 30 +++++++++++++++++++++++- - 1 file changed, 29 insertions(+), 1 deletion(-) - -diff --git a/components/engine/pkg/pidfile/pidfile.go b/components/engine/pkg/pidfile/pidfile.go -index 0617a89e5f..485c00138b 100644 ---- a/components/engine/pkg/pidfile/pidfile.go -+++ b/components/engine/pkg/pidfile/pidfile.go -@@ -4,6 +4,7 @@ - package pidfile // import "github.com/docker/docker/pkg/pidfile" - - import ( -+ "bufio" - "fmt" - "io/ioutil" - "os" -@@ -19,12 +20,39 @@ type PIDFile struct { - path string - } - -+// isSameApplication check whether the pid exist in pidfile -+// is the the same application we are going to run. -+func isSameApplication(pid int) (bool, error) { -+ path := filepath.Join("/proc", strconv.Itoa(pid), "status") -+ file, err := os.Open(path) -+ if err != nil { -+ return false, err -+ } -+ defer file.Close() -+ sc := bufio.NewScanner(file) -+ for sc.Scan() { -+ lens := strings.Split(sc.Text(), ":") -+ if len(lens) == 2 && strings.TrimSpace(lens[0]) == "Name" { -+ if strings.TrimSpace(lens[1]) == os.Args[0] { -+ return true, nil -+ } -+ return false, nil -+ } -+ } -+ if err := sc.Err(); err != nil { -+ return false, err -+ } -+ return false, nil -+} -+ - func checkPIDFileAlreadyExists(path string) error { - if pidByte, err := ioutil.ReadFile(path); err == nil { - pidString := strings.TrimSpace(string(pidByte)) - if pid, err := strconv.Atoi(pidString); err == nil { - if processExists(pid) { -- return fmt.Errorf("pid file found, ensure docker is not running or delete %s", path) -+ if same, err := isSameApplication(pid); same || (err != nil && !os.IsNotExist(err)) { -+ return fmt.Errorf("pid file found, ensure docker is not running or delete %s", path) -+ } - } - } - } --- -2.17.1 - diff --git a/patch/0044-plugin-Fix-plugin-security-bug-caused-by-unch.patch b/patch/0044-plugin-Fix-plugin-security-bug-caused-by-unch.patch deleted file mode 100644 index d3bffe0..0000000 --- a/patch/0044-plugin-Fix-plugin-security-bug-caused-by-unch.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 75d53c469ea6115db0386155262565a8aa15556d Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 3 Jan 2019 16:04:37 +0800 -Subject: [PATCH 044/111] plugin: Fix plugin security bug caused by - unchecked plugin name - -reason: cherry-pick commits to docker-18.09 - -cherry-pick from 48c9622f82 | * plugin,bugfix: Fix plugin security bug -caused by unchecked plugin name - -Docker may activate plugins outside plugin directory if plugin name -contains string like "../../". This patch fix this bug by checking the -combined plugin path before use it. - -fix issue docker/docker#268 - -Change-Id: Icff8b24e50fc92721149267bc8c29a8652046d8a -Signed-off-by: majiuyue -Signed-off-by: jingrui ---- - components/engine/pkg/plugins/discovery.go | 27 ++++++++++++++++------ - components/engine/pkg/plugins/plugins.go | 2 +- - 2 files changed, 21 insertions(+), 8 deletions(-) - -diff --git a/components/engine/pkg/plugins/discovery.go b/components/engine/pkg/plugins/discovery.go -index 4b79bd29ad..51f1d8ebea 100644 ---- a/components/engine/pkg/plugins/discovery.go -+++ b/components/engine/pkg/plugins/discovery.go -@@ -14,6 +14,8 @@ import ( - ) - - var ( -+ // ErrForbidden plugin sock/spec outside allowed location -+ ErrForbidden = errors.New("plugin outside allowed location") - // ErrNotFound plugin not found - ErrNotFound = errors.New("plugin not found") - socketsPath = "/run/docker/plugins" -@@ -82,7 +84,10 @@ func Scan() ([]string, error) { - - // Plugin returns the plugin registered with the given name (or returns an error). - func (l *localRegistry) Plugin(name string) (*Plugin, error) { -- socketpaths := pluginPaths(socketsPath, name, ".sock") -+ socketpaths, err := pluginPaths(socketsPath, name, ".sock") -+ if err != nil { -+ return nil, ErrForbidden -+ } - - for _, p := range socketpaths { - if fi, err := os.Stat(p); err == nil && fi.Mode()&os.ModeSocket != 0 { -@@ -92,8 +97,10 @@ func (l *localRegistry) Plugin(name string) (*Plugin, error) { - - var txtspecpaths []string - for _, p := range specsPaths { -- txtspecpaths = append(txtspecpaths, pluginPaths(p, name, ".spec")...) -- txtspecpaths = append(txtspecpaths, pluginPaths(p, name, ".json")...) -+ for _, ext := range []string{".spec", ".json"} { -+ paths, _ := pluginPaths(p, name, ext) -+ txtspecpaths = append(txtspecpaths, paths...) -+ } - } - - for _, p := range txtspecpaths { -@@ -146,9 +153,15 @@ func readPluginJSONInfo(name, path string) (*Plugin, error) { - return &p, nil - } - --func pluginPaths(base, name, ext string) []string { -- return []string{ -- filepath.Join(base, name+ext), -- filepath.Join(base, name, name+ext), -+func pluginPaths(base, name, ext string) ([]string, error) { -+ paths := []string{ -+ filepath.Clean(filepath.Join(base, name+ext)), -+ filepath.Clean(filepath.Join(base, name, name+ext)), -+ } -+ for _, p := range paths { -+ if !strings.HasPrefix(p, base) { -+ return nil, ErrForbidden -+ } - } -+ return paths, nil - } -diff --git a/components/engine/pkg/plugins/plugins.go b/components/engine/pkg/plugins/plugins.go -index 6962079df9..8a6fbeda29 100644 ---- a/components/engine/pkg/plugins/plugins.go -+++ b/components/engine/pkg/plugins/plugins.go -@@ -208,7 +208,7 @@ func loadWithRetry(name string, retry bool) (*Plugin, error) { - for { - pl, err := registry.Plugin(name) - if err != nil { -- if !retry { -+ if !retry || err == ErrForbidden { - return nil, err - } - --- -2.17.1 - diff --git a/patch/0045-overlay-safely-remove-overlay-layer-directory.patch b/patch/0045-overlay-safely-remove-overlay-layer-directory.patch deleted file mode 100644 index c639ac3..0000000 --- a/patch/0045-overlay-safely-remove-overlay-layer-directory.patch +++ /dev/null @@ -1,122 +0,0 @@ -From d2901f9efd4b1b26c995ea1c61663a14bc9c55d6 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 3 Jan 2019 16:25:23 +0800 -Subject: [PATCH 045/111] overlay: safely remove overlay layer - directory - -reason: cherry-pick commits to docker-18.09 - -merge from -0af3bf355a * safely remove overlay layer directory -e2b1d6827b * docker: add link string validation - ---- -safely remove overlay layer directory - -do not recover link if the format is illegal -do not remove illegal link string - -Signed-off-by: Deng Guangxing ---- -docker: add link string validation - -validate link string with restrict reqirements, not just stringLen. -Shukui Yang - -Signed-off-by: Deng Guangxing -Signed-off-by: yangshukui - -Change-Id: Ie4f47b942c7e89bd6632d310c1cb34533ed5726b -Signed-off-by: jingrui ---- - .../daemon/graphdriver/overlay2/overlay.go | 30 +++++++++++++++++-- - .../daemon/graphdriver/overlay2/randomid.go | 7 +++++ - 2 files changed, 34 insertions(+), 3 deletions(-) - -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index 722d65b11a..773d5232cc 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -419,6 +419,10 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr - } - - lid := generateID(idLength) -+ if !verifyID(lid, idLength) { -+ // this should never happen -+ return fmt.Errorf("[overlay2], generated link string(%s) illegal", lid) -+ } - if err := os.Symlink(path.Join("..", id, "diff"), path.Join(d.home, linkDir, lid)); err != nil { - return err - } -@@ -491,6 +495,9 @@ func (d *Driver) getLower(parent string) (string, error) { - if err != nil { - return "", err - } -+ if !verifyID(string(parentLink), idLength) { -+ return "", fmt.Errorf("illegal link string: %s", parentLink) -+ } - lowers := []string{path.Join(linkDir, string(parentLink))} - - parentLower, err := ioutil.ReadFile(path.Join(parentDir, lowerFile)) -@@ -570,7 +577,7 @@ func (d *Driver) Remove(id string) error { - dir := d.dir(id) - lid, err := ioutil.ReadFile(path.Join(dir, "link")) - if err == nil { -- if len(lid) == 0 { -+ if !verifyID(string(lid), idLength) { - logrus.WithField("storage-driver", "overlay2").Errorf("refusing to remove empty link for layer %v", id) - } else if err := os.RemoveAll(path.Join(d.home, linkDir, string(lid))); err != nil { - logrus.WithField("storage-driver", "overlay2").Debugf("Failed to remove link: %v", err) -@@ -703,8 +710,25 @@ func (d *Driver) Put(id string) error { - - // Exists checks to see if the id is already mounted. - func (d *Driver) Exists(id string) bool { -- _, err := os.Stat(d.dir(id)) -- return err == nil -+ _, rerr := os.Stat(d.dir(id)) -+ if rerr == nil { -+ lstr, err := ioutil.ReadFile(path.Join(d.dir(id), "link")) -+ // link is valid -+ if err == nil && verifyID(string(lstr), idLength) { -+ // check symlink -+ _, rerr = os.Stat(path.Join(d.home, linkDir, string(lstr))) -+ if rerr != nil { -+ os.RemoveAll(path.Join(d.home, linkDir, string(lstr))) -+ -+ logrus.Infof("[overlay2]: symlink (%s) is missing, create a new one", lstr) -+ if rerr = os.Symlink(path.Join("..", id, "diff"), path.Join(d.home, linkDir, string(lstr))); rerr != nil { -+ return false -+ } -+ } -+ return true -+ } -+ } -+ return false - } - - // isParent determines whether the given parent is the direct parent of the -diff --git a/components/engine/daemon/graphdriver/overlay2/randomid.go b/components/engine/daemon/graphdriver/overlay2/randomid.go -index 842c06127f..933d9fccb6 100644 ---- a/components/engine/daemon/graphdriver/overlay2/randomid.go -+++ b/components/engine/daemon/graphdriver/overlay2/randomid.go -@@ -8,6 +8,7 @@ import ( - "fmt" - "io" - "os" -+ "regexp" - "syscall" - "time" - -@@ -79,3 +80,9 @@ func retryOnError(err error) bool { - - return false - } -+ -+func verifyID(id string, l int) bool { -+ regstr := fmt.Sprintf("^[A-Z0-9]{%d}$", l) -+ rgxp := regexp.MustCompile(regstr) -+ return rgxp.MatchString(id) -+} --- -2.17.1 - diff --git a/patch/0046-debug-add-more-error-info-when-dial-docker.so.patch b/patch/0046-debug-add-more-error-info-when-dial-docker.so.patch deleted file mode 100644 index fd26143..0000000 --- a/patch/0046-debug-add-more-error-info-when-dial-docker.so.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 024a67b1d7ccfa85bba14318cd4fbbe78ecc8b7e Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 10 Jan 2019 00:17:01 +0800 -Subject: [PATCH 046/111] debug: add more error info when dial - docker.sock fail - -reason: cherry-pick commits to docker-18.09 - -add more error info when dial docker.sock fail - -cherry-pick from 1.11.2: 91c7491 - -Change-Id: I3c7219d44be752ecde92479f03c0e2cee3ccb4a0 -Signed-off-by: lujingxiao -Signed-off-by: xiadanni ---- - components/engine/client/request.go | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - -diff --git a/components/engine/client/request.go b/components/engine/client/request.go -index a19d62aa52..855b84d6ac 100644 ---- a/components/engine/client/request.go -+++ b/components/engine/client/request.go -@@ -10,6 +10,7 @@ import ( - "net" - "net/http" - "net/url" -+ "regexp" - "os" - "strings" - -@@ -156,11 +157,19 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp - - if err, ok := err.(net.Error); ok { - if err.Timeout() { -- return serverResp, ErrorConnectionFailed(cli.host) -+ return serverResp, fmt.Errorf("Cannot connect to the Docker daemon failed for timeout.") - } - if !err.Temporary() { -- if strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "dial unix") { -- return serverResp, ErrorConnectionFailed(cli.host) -+ if strings.Contains(err.Error(), "dial unix") { -+ var err2 error -+ r, rerr := regexp.Compile("dial unix.*") -+ if rerr != nil { -+ err2 = fmt.Errorf("Cannot connect to the Docker daemon failed for dial unix.") -+ } else { -+ rbytes := r.Find([]byte(err.Error())) -+ err2 = fmt.Errorf("Cannot connect to the Docker daemon failed for %s", string(rbytes)) -+ } -+ return serverResp, err2 - } - } - } --- -2.17.1 - diff --git a/patch/0047-docker-fix-panic-slice-bounds-out-of-range.patch b/patch/0047-docker-fix-panic-slice-bounds-out-of-range.patch deleted file mode 100644 index 975fac0..0000000 --- a/patch/0047-docker-fix-panic-slice-bounds-out-of-range.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 8483caa076b11f33e9a4c578b8aefce127468e66 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Fri, 11 Jan 2019 12:18:27 +0800 -Subject: [PATCH 047/111] docker: fix panic slice bounds out of range - -reason: fix panic - -panic: runtime error: slice bounds out of range - -goroutine 1 [running]: -github.com/docker/docker/daemon.parseInitVersion(0xc4209da600, 0x22, 0x22, 0x600, 0xc4209da600, 0x22, 0x28, 0x0) - /go/src/github.com/docker/docker/daemon/info_unix.go:163 +0x3ce -github.com/docker/docker/daemon.(*Daemon).fillPlatformInfo(0xc4206e21e0, 0xc42009cc00, 0xc42081d220) - /go/src/github.com/docker/docker/daemon/info_unix.go:68 +0x115f -github.com/docker/docker/daemon.(*Daemon).SystemInfo(0xc4206e21e0, 0x0, 0x0, 0xc42020d3c0) - /go/src/github.com/docker/docker/daemon/info.go:75 +0x7e8 -github.com/docker/docker/daemon.NewDaemon(0x55b515ace080, 0xc4201ab400, 0xc4207c5400, 0xc4207602d0, 0x0, 0x0, 0x0) - /go/src/github.com/docker/docker/daemon/daemon.go:1080 +0x2c87 -main.(*DaemonCli).start(0xc420727260, 0xc42016f6e0, 0x0, 0x0) - /go/src/github.com/docker/docker/cmd/dockerd/daemon.go:180 +0x74f -main.runDaemon(0xc42016f6e0, 0xc420194600, 0x0) - /go/src/github.com/docker/docker/cmd/dockerd/docker_unix.go:7 +0x47 -main.newDaemonCommand.func1(0xc42076d680, 0xc420190d80, 0x0, 0x8, 0x0, 0x0) - /go/src/github.com/docker/docker/cmd/dockerd/docker.go:29 +0x5d -github.com/docker/docker/vendor/github.com/spf13/cobra.(*Command).execute(0xc42076d680, 0xc42003a0a0, 0x8, 0x8, 0xc42076d680, 0xc42003a0a0) - /go/src/github.com/docker/docker/vendor/github.com/spf13/cobra/command.go:762 +0x46a -github.com/docker/docker/vendor/github.com/spf13/cobra.(*Command).ExecuteC(0xc42076d680, 0x55b515aa3350, 0x55b51565f0c0, 0x55b515aa3360) - /go/src/github.com/docker/docker/vendor/github.com/spf13/cobra/command.go:852 +0x30c -github.com/docker/docker/vendor/github.com/spf13/cobra.(*Command).Execute(0xc42076d680, 0xc42000e020, 0x55b5138f336f) - /go/src/github.com/docker/docker/vendor/github.com/spf13/cobra/command.go:800 +0x2d -main.main() - /go/src/github.com/docker/docker/cmd/dockerd/docker.go:70 +0xa2 - -Change-Id: Iafadb0c9215e1840c084637ebc96f5ef4d004cbd -Signed-off-by: jingrui ---- - components/engine/daemon/info_unix.go | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/components/engine/daemon/info_unix.go b/components/engine/daemon/info_unix.go -index 55b6c6e79b..c53804edec 100644 ---- a/components/engine/daemon/info_unix.go -+++ b/components/engine/daemon/info_unix.go -@@ -160,7 +160,11 @@ func parseInitVersion(v string) (types.Commit, error) { - gitParts := strings.Split(parts[1], ".") - if len(gitParts) == 2 && gitParts[0] == "git" { - version.ID = gitParts[1] -- version.Expected = dockerversion.InitCommitID[0:len(version.ID)] -+ n := len(dockerversion.InitCommitID) -+ if n > len(version.ID) { -+ n = len(version.ID) -+ } -+ version.Expected = dockerversion.InitCommitID[0:n] - } - } - if version.ID == "" && strings.HasPrefix(parts[0], "tini version ") { --- -2.17.1 - diff --git a/patch/0048-docker-check-metadata-when-load-layer.patch b/patch/0048-docker-check-metadata-when-load-layer.patch deleted file mode 100644 index a4ded6f..0000000 --- a/patch/0048-docker-check-metadata-when-load-layer.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 7eb6d78447ed19a19c57331cb63e58097d29caeb Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Tue, 8 Jan 2019 18:19:16 +0800 -Subject: [PATCH 048/111] docker: check metadata when load layer - -reason:check metadata when load layer - -Cherry-pick from docker 1.11.2: -- 41795d7 check metadata when load layer - -Change-Id: Ia1734172a33d0ebe29ddb4b76d207da2981a137a -Signed-off-by: Liu Hua -Signed-off-by: zhangyu235 ---- - components/engine/layer/layer_store.go | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/components/engine/layer/layer_store.go b/components/engine/layer/layer_store.go -index 5decb0bdce..f22e9c666c 100644 ---- a/components/engine/layer/layer_store.go -+++ b/components/engine/layer/layer_store.go -@@ -193,6 +193,11 @@ func (ls *layerStore) loadLayer(layer ChainID) (l *roLayer, err error) { - return nil, err - } - cl.parent = p -+ } else { -+ _, err := ls.driver.GetMetadata(cacheID) -+ if err != nil { -+ return nil, fmt.Errorf("cacheID %s for layer %s does not have metadata ", cacheID, layer) -+ } - } - - ls.layerMap[cl.chainID] = cl --- -2.17.1 - diff --git a/patch/0049-cleanup-cleanup-useless-netns-file-in-var-run.patch b/patch/0049-cleanup-cleanup-useless-netns-file-in-var-run.patch deleted file mode 100644 index df09f7a..0000000 --- a/patch/0049-cleanup-cleanup-useless-netns-file-in-var-run.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 652be7c8c259c25adaed10f6f121a7d18283daa0 Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Tue, 8 Jan 2019 19:08:25 +0800 -Subject: [PATCH 049/111] cleanup: cleanup useless netns file in - /var/run/docker/netns - -reason:killing daemon would left useless netns file. -try to clean them up during daemon restore according to -activesandboxes - -cherrt-pick from docker 1.11.2: -- e657d09 cleanup useless netns file in /var/run/docker/netns - -Change-Id: I4bfff028a1ad2df9a42456b9f181db87d63c7cd7 -Signed-off-by: dengguangxing -Signed-off-by: zhangyu235 ---- - .../docker/libnetwork/controller.go | 2 ++ - .../docker/libnetwork/osl/namespace_linux.go | 33 +++++++++++++++++++ - 2 files changed, 35 insertions(+) - -diff --git a/components/engine/vendor/github.com/docker/libnetwork/controller.go b/components/engine/vendor/github.com/docker/libnetwork/controller.go -index 2896011dbf..95013d31d3 100644 ---- a/components/engine/vendor/github.com/docker/libnetwork/controller.go -+++ b/components/engine/vendor/github.com/docker/libnetwork/controller.go -@@ -247,6 +247,8 @@ func New(cfgOptions ...config.Option) (NetworkController, error) { - c.sandboxCleanup(c.cfg.ActiveSandboxes) - c.cleanupLocalEndpoints() - c.networkCleanup() -+ osl.NetnsFileCleanup(c.cfg.ActiveSandboxes) -+ - - if err := c.startExternalKeyListener(); err != nil { - return nil, err -diff --git a/components/engine/vendor/github.com/docker/libnetwork/osl/namespace_linux.go b/components/engine/vendor/github.com/docker/libnetwork/osl/namespace_linux.go -index bfc5d31a53..f97b286bcd 100644 ---- a/components/engine/vendor/github.com/docker/libnetwork/osl/namespace_linux.go -+++ b/components/engine/vendor/github.com/docker/libnetwork/osl/namespace_linux.go -@@ -586,6 +586,39 @@ func (n *networkNamespace) Restore(ifsopt map[string][]IfaceOption, routes []*ty - return nil - } - -+func NetnsFileCleanup(activeSandboxes map[string]interface{}) { -+ maxLen := 12 -+ dir, err := ioutil.ReadDir(prefix) -+ if err != nil { -+ logrus.Warnf("failed to open %s for netns cleanup: %s", prefix, err) -+ return -+ } -+ -+ activeSandboxesMap := make(map[string]string) -+ // shorten active sandboxes id to 12 char -+ for ac, _ := range activeSandboxes { -+ shortid := ac[:maxLen] -+ activeSandboxesMap[shortid] = shortid -+ } -+ -+ for _, v := range dir { -+ id := v.Name() -+ // skip if id length is not 12, like default -+ if len(id) != maxLen { -+ continue -+ } -+ -+ if _, ok := activeSandboxesMap[id]; !ok { -+ path := filepath.Join(prefix, id) -+ // cleanup netns file if not active -+ syscall.Unmount(path, syscall.MNT_DETACH) -+ if err := os.Remove(path); err != nil { -+ logrus.Warnf("Failed to cleanup netns file %s: %s", path, err) -+ } -+ } -+ } -+} -+ - // Checks whether IPv6 needs to be enabled/disabled on the loopback interface - func (n *networkNamespace) checkLoV6() { - var ( --- -2.17.1 - diff --git a/patch/0050-volume-Make-v.opts-to-nil-if-opts.json-is-nul.patch b/patch/0050-volume-Make-v.opts-to-nil-if-opts.json-is-nul.patch deleted file mode 100644 index 26e2262..0000000 --- a/patch/0050-volume-Make-v.opts-to-nil-if-opts.json-is-nul.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 415f93f45004d4082d3a7bcfdee122b584cd2e57 Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Tue, 8 Jan 2019 19:34:41 +0800 -Subject: [PATCH 050/111] volume: Make v.opts to nil if opts.json is - null - -reason:Make v.opts to nil if opts.json is null - -cherry-pick from docker 1.11.2: -- 1b9344b Make v.opts to nil if opts.json is null - -Change-Id: I59d6ebb41cbb908d72beb4f9f6c645cb7ae2c4ba -Signed-off-by: Lei Jitang -Signed-off-by: zhangyu235 ---- - components/engine/volume/local/local.go | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/components/engine/volume/local/local.go b/components/engine/volume/local/local.go -index 7190de9ed6..2e865815a9 100644 ---- a/components/engine/volume/local/local.go -+++ b/components/engine/volume/local/local.go -@@ -89,6 +89,13 @@ func New(scope string, rootIdentity idtools.Identity) (*Root, error) { - v.opts = &opts - } - -+ // For the local volumes created without options, -+ // the opts.json is null, so all the value in v.opts is null -+ // We should make v.opts to nil to avoid v.mount -+ if v.opts != nil && v.opts.MountType == "" && v.opts.MountOpts == "" && v.opts.MountDevice == "" { -+ v.opts = nil -+ } -+ - // unmount anything that may still be mounted (for example, from an unclean shutdown) - mount.Unmount(v.path) - } --- -2.17.1 - diff --git a/patch/0051-docker-fix-panic-when-load-maliciously-image.patch b/patch/0051-docker-fix-panic-when-load-maliciously-image.patch deleted file mode 100644 index 5e372e2..0000000 --- a/patch/0051-docker-fix-panic-when-load-maliciously-image.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 1fe0a4bfad5d7fa418f4e726211f4f037e59cfee Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Tue, 8 Jan 2019 19:47:28 +0800 -Subject: [PATCH 051/111] docker: fix panic when load maliciously - image - -reason:fix oom panic when load maliciously modified image with -huge size manifest files - -cherry-pick from docker 1.11.2: -- bbe29c3 fix panic when load maliciously image - -Change-Id: I2525e492fac31c33d3ba7275c95b570322a05025 -Signed-off-by: leizhongkai -Signed-off-by: zhangyu235 ---- - components/engine/image/tarexport/load.go | 28 +++++++++++++++++++ - .../engine/image/tarexport/tarexport.go | 1 + - 2 files changed, 29 insertions(+) - -diff --git a/components/engine/image/tarexport/load.go b/components/engine/image/tarexport/load.go -index 786214383e..b9f8f7e3ac 100644 ---- a/components/engine/image/tarexport/load.go -+++ b/components/engine/image/tarexport/load.go -@@ -49,6 +49,11 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool) - if err != nil { - return err - } -+ -+ if err = checkJsonFileSize(manifestPath); err != nil { -+ return err -+ } -+ - manifestFile, err := os.Open(manifestPath) - if err != nil { - if os.IsNotExist(err) { -@@ -72,6 +77,9 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool) - if err != nil { - return err - } -+ if err = checkJsonFileSize(configPath); err != nil { -+ return err -+ } - config, err := ioutil.ReadFile(configPath) - if err != nil { - return err -@@ -246,6 +254,11 @@ func (l *tarexporter) legacyLoad(tmpDir string, outStream io.Writer, progressOut - if err != nil { - return err - } -+ -+ if err = checkJsonFileSize(repositoriesPath); err != nil { -+ return err -+ } -+ - repositoriesFile, err := os.Open(repositoriesPath) - if err != nil { - return err -@@ -286,6 +299,9 @@ func (l *tarexporter) legacyLoadImage(oldID, sourceDir string, loadedMap map[str - if err != nil { - return err - } -+ if err = checkJsonFileSize(configPath); err != nil { -+ return err -+ } - imageJSON, err := ioutil.ReadFile(configPath) - if err != nil { - logrus.Debugf("Error reading json: %v", err) -@@ -413,6 +429,18 @@ func checkValidParent(img, parent *image.Image) bool { - return true - } - -+func checkJsonFileSize(path string) error { -+ fileInfo, err := os.Stat(path) -+ if err != nil { -+ return err -+ } -+ fileSize := fileInfo.Size() -+ if fileSize > maxJsonFileSize { -+ return fmt.Errorf("%s is too large", filepath.Base(path)) -+ } -+ return nil -+} -+ - func checkCompatibleOS(imageOS string) error { - // always compatible if the images OS matches the host OS; also match an empty image OS - if imageOS == runtime.GOOS || imageOS == "" { -diff --git a/components/engine/image/tarexport/tarexport.go b/components/engine/image/tarexport/tarexport.go -index beff668cd8..f23fe6f8bb 100644 ---- a/components/engine/image/tarexport/tarexport.go -+++ b/components/engine/image/tarexport/tarexport.go -@@ -13,6 +13,7 @@ const ( - legacyConfigFileName = "json" - legacyVersionFileName = "VERSION" - legacyRepositoriesFileName = "repositories" -+ maxJsonFileSize = (10 * 1024 * 1024) - ) - - type manifestItem struct { --- -2.17.1 - diff --git a/patch/0052-docker-Lock-the-RWLayer-while-committing-expo.patch b/patch/0052-docker-Lock-the-RWLayer-while-committing-expo.patch deleted file mode 100644 index 17ebbc2..0000000 --- a/patch/0052-docker-Lock-the-RWLayer-while-committing-expo.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 568c9501d56ccff1806253f9e2289fdd5c002231 Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Thu, 17 Jan 2019 20:03:14 +0800 -Subject: [PATCH 052/111] docker: Lock the RWLayer while - committing/exporting - -reason:Add a rw mutex to `mountLayer/roLayer/emptyLayer` and introduce -new methods `RLockRWLayer()` and `RUnlockRWLayer()` to `RWLayer`. -Now the rw layer of the container would be locked to block removal of -that layer. - -Cherry-pick from docker 1.11.2: -- 2923a77c Lock the RWLayer while committing/exporting - -Change-Id: I11d6dcb60a23fe3516cebaed36d19aabaa863769 -Signed-off-by: Yuanhong Peng -Signed-off-by: zhangyu235 ---- - components/engine/daemon/commit.go | 2 ++ - components/engine/daemon/export.go | 2 ++ - components/engine/layer/empty.go | 13 ++++++++++++- - components/engine/layer/layer.go | 7 +++++++ - components/engine/layer/layer_store.go | 2 ++ - components/engine/layer/mounted_layer.go | 10 ++++++++++ - components/engine/layer/ro_layer.go | 10 ++++++++++ - 7 files changed, 45 insertions(+), 1 deletion(-) - -diff --git a/components/engine/daemon/commit.go b/components/engine/daemon/commit.go -index 0f6f440514..fc7d2782ef 100644 ---- a/components/engine/daemon/commit.go -+++ b/components/engine/daemon/commit.go -@@ -155,6 +155,8 @@ func (daemon *Daemon) CreateImageFromContainer(name string, c *backend.CreateIma - return "", err - } - -+ container.RWLayer.RLockRWLayer() -+ defer container.RWLayer.RUnlockRWLayer() - id, err := daemon.imageService.CommitImage(backend.CommitConfig{ - Author: c.Author, - Comment: c.Comment, -diff --git a/components/engine/daemon/export.go b/components/engine/daemon/export.go -index 27bc35967d..ebd2d75f40 100644 ---- a/components/engine/daemon/export.go -+++ b/components/engine/daemon/export.go -@@ -34,6 +34,8 @@ func (daemon *Daemon) ContainerExport(name string, out io.Writer) error { - return errdefs.Conflict(err) - } - -+ container.RWLayer.RLockRWLayer() -+ defer container.RWLayer.RUnlockRWLayer() - data, err := daemon.containerExport(container) - if err != nil { - return fmt.Errorf("Error exporting container %s: %v", name, err) -diff --git a/components/engine/layer/empty.go b/components/engine/layer/empty.go -index c81c702140..16a49a7abd 100644 ---- a/components/engine/layer/empty.go -+++ b/components/engine/layer/empty.go -@@ -6,13 +6,16 @@ import ( - "fmt" - "io" - "io/ioutil" -+ "sync" - ) - - // DigestSHA256EmptyTar is the canonical sha256 digest of empty tar file - - // (1024 NULL bytes) - const DigestSHA256EmptyTar = DiffID("sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef") - --type emptyLayer struct{} -+type emptyLayer struct { -+ sync.RWMutex -+} - - // EmptyLayer is a layer that corresponds to empty tar. - var EmptyLayer = &emptyLayer{} -@@ -55,6 +58,14 @@ func (el *emptyLayer) Metadata() (map[string]string, error) { - return make(map[string]string), nil - } - -+func (el *emptyLayer) RLockRWLayer() { -+ el.RLock() -+} -+ -+func (el *emptyLayer) RUnlockRWLayer() { -+ el.RUnlock() -+} -+ - // IsEmpty returns true if the layer is an EmptyLayer - func IsEmpty(diffID DiffID) bool { - return diffID == DigestSHA256EmptyTar -diff --git a/components/engine/layer/layer.go b/components/engine/layer/layer.go -index cb13c98d0b..e35a13135b 100644 ---- a/components/engine/layer/layer.go -+++ b/components/engine/layer/layer.go -@@ -145,6 +145,13 @@ type RWLayer interface { - - // Metadata returns the low level metadata for the mutable layer - Metadata() (map[string]string, error) -+ -+ // RLockRWLayer locks the RWLayer to block unmounting/removal -+ // of that layer -+ RLockRWLayer() -+ -+ // RUnlockRWLayer unlocks the RWLayer -+ RUnlockRWLayer() - } - - // Metadata holds information about a -diff --git a/components/engine/layer/layer_store.go b/components/engine/layer/layer_store.go -index f22e9c666c..7c80a29645 100644 ---- a/components/engine/layer/layer_store.go -+++ b/components/engine/layer/layer_store.go -@@ -666,6 +666,8 @@ func (ls *layerStore) ReleaseRWLayer(l RWLayer) ([]Metadata, error) { - return []Metadata{}, nil - } - -+ m.Lock() -+ defer m.Unlock() - if err := m.deleteReference(l); err != nil { - return nil, err - } -diff --git a/components/engine/layer/mounted_layer.go b/components/engine/layer/mounted_layer.go -index d6858c662c..66711d6cf7 100644 ---- a/components/engine/layer/mounted_layer.go -+++ b/components/engine/layer/mounted_layer.go -@@ -2,6 +2,7 @@ package layer // import "github.com/docker/docker/layer" - - import ( - "io" -+ "sync" - - "github.com/docker/docker/pkg/archive" - "github.com/docker/docker/pkg/containerfs" -@@ -16,6 +17,7 @@ type mountedLayer struct { - layerStore *layerStore - - references map[RWLayer]*referencedRWLayer -+ sync.RWMutex - } - - func (ml *mountedLayer) cacheParent() string { -@@ -58,6 +60,14 @@ func (ml *mountedLayer) Metadata() (map[string]string, error) { - return ml.layerStore.driver.GetMetadata(ml.mountID) - } - -+func (ml *mountedLayer) RLockRWLayer() { -+ ml.RLock() -+} -+ -+func (ml *mountedLayer) RUnlockRWLayer() { -+ ml.RUnlock() -+} -+ - func (ml *mountedLayer) getReference() RWLayer { - ref := &referencedRWLayer{ - mountedLayer: ml, -diff --git a/components/engine/layer/ro_layer.go b/components/engine/layer/ro_layer.go -index 3555e8b027..59bcf17d18 100644 ---- a/components/engine/layer/ro_layer.go -+++ b/components/engine/layer/ro_layer.go -@@ -3,6 +3,7 @@ package layer // import "github.com/docker/docker/layer" - import ( - "fmt" - "io" -+ "sync" - - "github.com/docker/distribution" - "github.com/opencontainers/go-digest" -@@ -19,6 +20,7 @@ type roLayer struct { - - referenceCount int - references map[Layer]struct{} -+ sync.RWMutex - } - - // TarStream for roLayer guarantees that the data that is produced is the exact -@@ -92,6 +94,14 @@ func (rl *roLayer) Metadata() (map[string]string, error) { - return rl.layerStore.driver.GetMetadata(rl.cacheID) - } - -+func (rl *roLayer) RLockRWLayer() { -+ rl.RLock() -+} -+ -+func (rl *roLayer) RUnlockRWLayer() { -+ rl.RUnlock() -+} -+ - type referencedCacheLayer struct { - *roLayer - } --- -2.17.1 - diff --git a/patch/0053-docker-remove-init-layer-when-no-space-to-cre.patch b/patch/0053-docker-remove-init-layer-when-no-space-to-cre.patch deleted file mode 100644 index b2443f8..0000000 --- a/patch/0053-docker-remove-init-layer-when-no-space-to-cre.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 2afc35ae4a34d70007bccb971d1f074574a3e282 Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Thu, 17 Jan 2019 20:13:18 +0800 -Subject: [PATCH 053/111] docker: remove init layer when no space to - create RW layer - -reason:remove init layer when no space to create RW layer - -Cherry-pick from docker 1.11.2: -- 24d00cf remove init layer when no space to create RW layer - -Change-Id: I3ef9fa1073c12242f5f56997883fe831d9497a9a -Signed-off-by: lujingxiao -Signed-off-by: zhangyu235 ---- - components/engine/layer/layer_store.go | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/components/engine/layer/layer_store.go b/components/engine/layer/layer_store.go -index 7c80a29645..20c0195b79 100644 ---- a/components/engine/layer/layer_store.go -+++ b/components/engine/layer/layer_store.go -@@ -598,6 +598,20 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWL - // Release parent chain if error - defer func() { - if err != nil { -+ m.Lock() -+ if err := ls.driver.Remove(m.mountID); err != nil { -+ logrus.Errorf("Error removing mounted layer during create rw layer %s: %s", m.name, err) -+ } -+ if m.initID != "" { -+ if err := ls.driver.Remove(m.initID); err != nil { -+ logrus.Errorf("Error removing init layer during create rw layer %s: %s", m.name, err) -+ } -+ } -+ if err := ls.store.RemoveMount(m.name); err != nil { -+ logrus.Errorf("Error removing mount metadata during create rw layer %s: %s", m.name, err) -+ } -+ m.Unlock() -+ - ls.layerL.Lock() - ls.releaseLayer(p) - ls.layerL.Unlock() --- -2.17.1 - diff --git a/patch/0054-docker-remove-init-layer-if-fails-in-initMoun.patch b/patch/0054-docker-remove-init-layer-if-fails-in-initMoun.patch deleted file mode 100644 index 0d8d65e..0000000 --- a/patch/0054-docker-remove-init-layer-if-fails-in-initMoun.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 1fb61b2addb6043e8403a613b4229c20070f8bfe Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Fri, 18 Jan 2019 17:38:47 +0800 -Subject: [PATCH 054/111] docker: remove init layer if fails in - initMount - -reason:remove init layer if fails in initMount - -Cherry-pick from docker 1.11.2: -- 673c733 remove init layer if fails in initMount -during initMount, operation could fails after device -created, it should be removed during rollback -Signed-off-by: lujingxiao -------- -- 424970f fix metadata file deleted mistakely -fix devicemapper metadata file "base" be deleted mistakely -Signed-off-by: leizhongkai - -Change-Id: Ieb40a8cfd3272abf28bfb046d77ecb61aea02bfa -Signed-off-by: zhangyu235 ---- - components/engine/layer/layer_store.go | 22 +++++++++++++++------- - 1 file changed, 15 insertions(+), 7 deletions(-) - -diff --git a/components/engine/layer/layer_store.go b/components/engine/layer/layer_store.go -index 20c0195b79..cbb1ee4a19 100644 ---- a/components/engine/layer/layer_store.go -+++ b/components/engine/layer/layer_store.go -@@ -599,16 +599,16 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWL - defer func() { - if err != nil { - m.Lock() -- if err := ls.driver.Remove(m.mountID); err != nil { -- logrus.Errorf("Error removing mounted layer during create rw layer %s: %s", m.name, err) -+ if deferErr := ls.driver.Remove(m.mountID); deferErr != nil { -+ logrus.Errorf("Error removing mounted layer during create rw layer %s: %s", m.name, deferErr) - } - if m.initID != "" { -- if err := ls.driver.Remove(m.initID); err != nil { -- logrus.Errorf("Error removing init layer during create rw layer %s: %s", m.name, err) -+ if deferErr := ls.driver.Remove(m.initID); deferErr != nil { -+ logrus.Errorf("Error removing init layer during create rw layer %s: %s", m.name, deferErr) - } - } -- if err := ls.store.RemoveMount(m.name); err != nil { -- logrus.Errorf("Error removing mount metadata during create rw layer %s: %s", m.name, err) -+ if deferErr := ls.store.RemoveMount(m.name); deferErr != nil { -+ logrus.Errorf("Error removing mount metadata during create rw layer %s: %s", m.name, deferErr) - } - m.Unlock() - -@@ -743,7 +743,7 @@ func (ls *layerStore) saveMount(mount *mountedLayer) error { - return nil - } - --func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc MountInit, storageOpt map[string]string) (string, error) { -+func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc MountInit, storageOpt map[string]string) (id string, err error) { - // Use "-init" to maintain compatibility with graph drivers - // which are expecting this layer with this special name. If all - // graph drivers can be updated to not rely on knowing about this layer -@@ -758,6 +758,14 @@ func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc Mou - if err := ls.driver.CreateReadWrite(initID, parent, createOpts); err != nil { - return "", err - } -+ defer func() { -+ if err != nil { -+ if deferErr := ls.driver.Remove(initID); deferErr != nil { -+ logrus.Errorf("Error removing init layer during init mount %s: %s", initID, deferErr) -+ } -+ } -+ }() -+ - p, err := ls.driver.Get(initID, "") - if err != nil { - return "", err --- -2.17.1 - diff --git a/patch/0055-docker-range-checking-for-memory-and-memory.s.patch b/patch/0055-docker-range-checking-for-memory-and-memory.s.patch deleted file mode 100644 index af6cbff..0000000 --- a/patch/0055-docker-range-checking-for-memory-and-memory.s.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 04094d4f0ca583bf2a3eccc390515840ad322853 Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Thu, 17 Jan 2019 20:45:45 +0800 -Subject: [PATCH 055/111] docker: range checking for memory and - memory.swap - -reason:range checking for memory and memory.swap, avoid overflow - -Cherry-pick from docker 1.11.2: -- 3dd33a7 range checking for memory and memory.swap - -Change-Id: I1736627a3f847decd36117f307a4919707908b32 -Signed-off-by: stella -Signed-off-by: zhangyu235 ---- - components/cli/vendor/github.com/docker/go-units/size.go | 4 ++++ - components/engine/daemon/daemon_unix.go | 5 ++++- - .../engine/vendor/github.com/docker/go-units/Checklist | 1 + - components/engine/vendor/github.com/docker/go-units/size.go | 4 ++++ - 4 files changed, 13 insertions(+), 1 deletion(-) - create mode 100644 components/engine/vendor/github.com/docker/go-units/Checklist - -diff --git a/components/cli/vendor/github.com/docker/go-units/size.go b/components/cli/vendor/github.com/docker/go-units/size.go -index 85f6ab0715..2b47b662ba 100644 ---- a/components/cli/vendor/github.com/docker/go-units/size.go -+++ b/components/cli/vendor/github.com/docker/go-units/size.go -@@ -104,5 +104,9 @@ func parseSize(sizeStr string, uMap unitMap) (int64, error) { - size *= float64(mul) - } - -+ if int64(size) < 0 { -+ return -1, fmt.Errorf("%s converted to int64 overflowed!", sizeStr) -+ } -+ - return int64(size), nil - } -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index d4a32a0b25..e48dfcd1ef 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -65,7 +65,7 @@ const ( - linuxMinCPUShares = 2 - linuxMaxCPUShares = 262144 - platformSupported = true -- // It's not kernel limit, we want this 4M limit to supply a reasonable functional container -+ // It's not kernel limit, we want this 4MB limit to supply a reasonable functional container - linuxMinMemory = 4194304 - // constants for remapped root settings - defaultIDSpecifier = "default" -@@ -293,6 +293,9 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf - if hostConfig.Memory > 0 && hostConfig.MemorySwap == 0 { - // By default, MemorySwap is set to twice the size of Memory. - hostConfig.MemorySwap = hostConfig.Memory * 2 -+ if hostConfig.MemorySwap < 0 { -+ return fmt.Errorf("invalid memory swap! The memory swap is double of memory, and should be less than the maximum of int64.") -+ } - } - if hostConfig.ShmSize == 0 { - hostConfig.ShmSize = config.DefaultShmSize -diff --git a/components/engine/vendor/github.com/docker/go-units/Checklist b/components/engine/vendor/github.com/docker/go-units/Checklist -new file mode 100644 -index 0000000000..6b3f1461e8 ---- /dev/null -+++ b/components/engine/vendor/github.com/docker/go-units/Checklist -@@ -0,0 +1 @@ -+add value range checking when converting units -\ No newline at end of file -diff --git a/components/engine/vendor/github.com/docker/go-units/size.go b/components/engine/vendor/github.com/docker/go-units/size.go -index 85f6ab0715..2b47b662ba 100644 ---- a/components/engine/vendor/github.com/docker/go-units/size.go -+++ b/components/engine/vendor/github.com/docker/go-units/size.go -@@ -104,5 +104,9 @@ func parseSize(sizeStr string, uMap unitMap) (int64, error) { - size *= float64(mul) - } - -+ if int64(size) < 0 { -+ return -1, fmt.Errorf("%s converted to int64 overflowed!", sizeStr) -+ } -+ - return int64(size), nil - } --- -2.17.1 - diff --git a/patch/0056-docker-check-cpuset.cpu-and-cpuset.mem.patch b/patch/0056-docker-check-cpuset.cpu-and-cpuset.mem.patch deleted file mode 100644 index 97234c7..0000000 --- a/patch/0056-docker-check-cpuset.cpu-and-cpuset.mem.patch +++ /dev/null @@ -1,132 +0,0 @@ -From e894ad0fa1c84d1a01afc47ccc52c3556121bbcd Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Tue, 8 Jan 2019 20:17:21 +0800 -Subject: [PATCH 056/111] docker: check cpuset.cpu and cpuset.mem - -reason:check cpuset.cpu and cpuset.mem - -cherry-pick from docker 1.11.2: -- 1c769f0 check cpuset.cpu and cpuset.mem -Signed-off-by: lujingxiao ------ -- 782f78f check cpuset.cpu and cpuset.mem -Signed-off-by: wangyi45 - -Change-Id: If21cad2023d737d03ba3d4a83e62d11fb2297945 -Signed-off-by: zhangyu235 ---- - components/engine/daemon/daemon_unix.go | 2 + - components/engine/pkg/sysinfo/sysinfo.go | 64 +++++++++++++++++++++++- - 2 files changed, 65 insertions(+), 1 deletion(-) - -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index e48dfcd1ef..b20c66e27b 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -499,6 +499,7 @@ func (daemon *Daemon) verifyContainerResources(hostConfig *containertypes.HostCo - } - cpusAvailable, err := sysInfo.IsCpusetCpusAvailable(resources.CpusetCpus) - if err != nil { -+ logrus.Errorf("Checking cpuset.cpus got %#v", err.Error()) - return warnings, errors.Wrapf(err, "Invalid value %s for cpuset cpus", resources.CpusetCpus) - } - if !cpusAvailable { -@@ -506,6 +507,7 @@ func (daemon *Daemon) verifyContainerResources(hostConfig *containertypes.HostCo - } - memsAvailable, err := sysInfo.IsCpusetMemsAvailable(resources.CpusetMems) - if err != nil { -+ logrus.Errorf("Checking cpuset.mems got %#v", err.Error()) - return warnings, errors.Wrapf(err, "Invalid value %s for cpuset mems", resources.CpusetMems) - } - if !memsAvailable { -diff --git a/components/engine/pkg/sysinfo/sysinfo.go b/components/engine/pkg/sysinfo/sysinfo.go -index 5d9320218c..7ea1be5daf 100644 ---- a/components/engine/pkg/sysinfo/sysinfo.go -+++ b/components/engine/pkg/sysinfo/sysinfo.go -@@ -1,6 +1,12 @@ - package sysinfo // import "github.com/docker/docker/pkg/sysinfo" - --import "github.com/docker/docker/pkg/parsers" -+import ( -+ "fmt" -+ "strconv" -+ "strings" -+ -+ "github.com/docker/docker/pkg/parsers" -+) - - // SysInfo stores information about which features a kernel supports. - // TODO Windows: Factor out platform specific capabilities. -@@ -123,6 +129,13 @@ func (c cgroupCpusetInfo) IsCpusetMemsAvailable(provided string) (bool, error) { - } - - func isCpusetListAvailable(provided, available string) (bool, error) { -+ if err := checkCPU(provided, available); err != nil { -+ if strings.Contains(err.Error(), "invalid format") { -+ return false, err -+ } -+ return false, nil -+ } -+ - parsedAvailable, err := parsers.ParseUintList(available) - if err != nil { - return false, err -@@ -147,6 +160,55 @@ func isCpusetListAvailable(provided, available string) (bool, error) { - return true, nil - } - -+func checkCPU(provided, available string) error { -+ if provided == "" { -+ return nil -+ } -+ -+ maxAvailable, err := maxCPU(available) -+ if err != nil { -+ return err -+ } -+ -+ maxRequest, err := maxCPU(provided) -+ if err != nil { -+ return err -+ } -+ -+ if maxRequest > maxAvailable { -+ return fmt.Errorf("invalid maxRequest is %d, max available: %d", maxRequest, maxAvailable) -+ } -+ -+ return nil -+} -+ -+func maxCPU(cores string) (int, error) { -+ var max int -+ split := strings.Split(cores, ",") -+ errInvalidFormat := fmt.Errorf("invalid format: %s", cores) -+ for _, r := range split { -+ if !strings.Contains(r, "-") { -+ v, err := strconv.Atoi(r) -+ if err != nil { -+ return max, errInvalidFormat -+ } -+ if v > max { -+ max = v -+ } -+ } else { -+ split := strings.SplitN(r, "-", 2) -+ end, err := strconv.Atoi(split[1]) -+ if err != nil { -+ return max, errInvalidFormat -+ } -+ if end > max { -+ max = end -+ } -+ } -+ } -+ return max, nil -+} -+ - // Returns bit count of 1, used by NumCPU - func popcnt(x uint64) (n byte) { - x -= (x >> 1) & 0x5555555555555555 --- -2.17.1 - diff --git a/patch/0057-docker-Ignore-ToDisk-error-in-StateChanged.patch b/patch/0057-docker-Ignore-ToDisk-error-in-StateChanged.patch deleted file mode 100644 index 9474729..0000000 --- a/patch/0057-docker-Ignore-ToDisk-error-in-StateChanged.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 241fc5d726e63e995d3518b734e18efff76284ac Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Fri, 18 Jan 2019 11:07:06 +0800 -Subject: [PATCH 057/111] docker: Ignore ToDisk error in StateChanged - -reason:If container is started normally, but failed to save - state to disk due to error "no space left on device", - then container can not be stopped, because container's - infomation in libcontainerd is cleaned up when error - occurred(so it can not process event 'exit'). - - We can ignore ToDisk error in StateChanged, it only - change status of container. Status is correct if docker - daemon not restart, because right status exists in memory. - If docker daemon restart, it will restore these status - using status of containerd, so status is also correct. - - This fix can break consistency of status in memory and - disk, but considering there is no space in disk, it is - not a big problem in this situation. Status in disk can - recover if disk have space and if ToDisk is written - again(for example, status changed). - - Fix issuse #322 - -Cherry-pick from docker 1.11.2: -- 5eb9015 Ignore ToDisk error in StateChanged - -Change-Id: Ifbdbffac06d1d739b03ea13962fb2d1fde7b5b3e -Signed-off-by: Fengtu Wang -Signed-off-by: zhangyu235 ---- - components/engine/daemon/monitor.go | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/components/engine/daemon/monitor.go b/components/engine/daemon/monitor.go -index 9b4452d7ef..807cdcaa89 100644 ---- a/components/engine/daemon/monitor.go -+++ b/components/engine/daemon/monitor.go -@@ -154,7 +154,11 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerd.EventType, ei libc - daemon.initHealthMonitor(c) - - if err := c.CheckpointTo(daemon.containersReplica); err != nil { -- return err -+ // If return err, container can not be stopped, see issue #322 for detail. -+ // Ignore error is safe, because if daemon not restart, status in memory is -+ // correct, and if daemon restart, it will restore status using status in -+ // containerd, so status in memory is also correct. -+ logrus.Debugf("Set status %v to disk failed: %v", e, err) - } - daemon.LogContainerEvent(c, "start") - } --- -2.17.1 - diff --git a/patch/0058-cleanup-cleanup-incompleted-device-while-dock.patch b/patch/0058-cleanup-cleanup-incompleted-device-while-dock.patch deleted file mode 100644 index 81b0037..0000000 --- a/patch/0058-cleanup-cleanup-incompleted-device-while-dock.patch +++ /dev/null @@ -1,35 +0,0 @@ -From ee64a0b5fd645d1765b0c50cbaab76c17bab9b28 Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Fri, 18 Jan 2019 14:46:21 +0800 -Subject: [PATCH 058/111] cleanup: cleanup incompleted device while - docker startup - -cleanup incompleted device while docker startup - -Change-Id: I9a9a96c655b61ac132fa7ed101dc9953c1bb613d -Signed-off-by: Wentao Zhang -Signed-off-by: zhangyu235 ---- - components/engine/daemon/graphdriver/devmapper/deviceset.go | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/components/engine/daemon/graphdriver/devmapper/deviceset.go b/components/engine/daemon/graphdriver/devmapper/deviceset.go -index b3e142e2ba..f4dc589c6e 100644 ---- a/components/engine/daemon/graphdriver/devmapper/deviceset.go -+++ b/components/engine/daemon/graphdriver/devmapper/deviceset.go -@@ -1753,6 +1753,12 @@ func (devices *DeviceSet) initDevmapper(doInit bool) (retErr error) { - } - logrus.Debugf("devmapper: remove broken device: %s", name) - } -+ if _, err := os.Stat(filepath.Join("/dev/mapper/", name)); err != nil { -+ if err := devicemapper.RemoveDevice(name); err != nil { -+ logrus.Warnf("devmapper: remove incompelete device(%s): %v", name, err) -+ } -+ logrus.Debugf("devmapper: remove incompelete device: %s", name) -+ } - } - - // Check for the existence of the thin-pool device --- -2.17.1 - diff --git a/patch/0059-overlay2-avoid-middle-state-while-removing-im.patch b/patch/0059-overlay2-avoid-middle-state-while-removing-im.patch deleted file mode 100644 index 65266cc..0000000 --- a/patch/0059-overlay2-avoid-middle-state-while-removing-im.patch +++ /dev/null @@ -1,110 +0,0 @@ -From ef238d650231f8346078536b6133f147df11283a Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Fri, 18 Jan 2019 19:21:39 +0800 -Subject: [PATCH 059/111] overlay2: avoid middle state while removing - images under overlay2 - -reason:avoid middle state while removing images under overlay2 - - kill -9 daemon while rmi images may cause some inconsistent state - of that image - - if image symlink is removed but the id directory remained. daemon - restart and load again, the images look fine but create container - with it will error out: - `docker: Error response from daemon: error creating overlay - mount to /var/lib/docker/overlay2/xxx-init/merged: - no such file or directory` - - This patch move symlink removal after directory removal, and check - link file state while daemon restore, to clean up stale links. - -Change-Id: I44328bc2261c9ec73bcdcbed3d741e569cd4a834 -Signed-off-by: Deng Guangxing -Signed-off-by: zhangyu235 ---- - .../daemon/graphdriver/overlay2/overlay.go | 40 ++++++++++++++++--- - 1 file changed, 34 insertions(+), 6 deletions(-) - -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index 773d5232cc..cf8993e9f3 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -229,6 +229,8 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap - return nil, fmt.Errorf("Storage Option overlay2.size only supported for backingFS XFS or ext4. Found %v", backingFs) - } - -+ d.cleanupLinkDir() -+ - // figure out whether "index=off" option is recognized by the kernel - _, err = os.Stat("/sys/module/overlay/parameters/index") - switch { -@@ -245,6 +247,19 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap - return d, nil - } - -+func (d *Driver) cleanupLinkDir() { -+ filepath.Walk(path.Join(d.home, linkDir), func(path string, f os.FileInfo, err error) error { -+ if _, serr := filepath.EvalSymlinks(path); serr != nil { -+ logrus.Warnf("[overlay2]: remove invalid symlink: %s", path) -+ os.RemoveAll(path) -+ } -+ // always return nil, to walk all the symlink -+ return nil -+ }) -+ -+ return -+} -+ - func parseOptions(options []string) (*overlayOptions, error) { - o := &overlayOptions{} - for _, option := range options { -@@ -575,8 +590,11 @@ func (d *Driver) Remove(id string) error { - d.locker.Lock(id) - defer d.locker.Unlock(id) - dir := d.dir(id) -- lid, err := ioutil.ReadFile(path.Join(dir, "link")) -- if err == nil { -+ lid, lerr := ioutil.ReadFile(path.Join(dir, "link")) -+ if err := system.EnsureRemoveAll(dir); err != nil && !os.IsNotExist(err) { -+ return err -+ } -+ if lerr == nil { - if !verifyID(string(lid), idLength) { - logrus.WithField("storage-driver", "overlay2").Errorf("refusing to remove empty link for layer %v", id) - } else if err := os.RemoveAll(path.Join(d.home, linkDir, string(lid))); err != nil { -@@ -568,9 +586,6 @@ func (d *Driver) Remove(id string) error { - } - } - -- if err := system.EnsureRemoveAll(dir); err != nil && !os.IsNotExist(err) { -- return err -- } - return nil - } - -@@ -710,7 +725,20 @@ func (d *Driver) Put(id string) error { - - // Exists checks to see if the id is already mounted. - func (d *Driver) Exists(id string) bool { -- _, rerr := os.Stat(d.dir(id)) -+ var rerr error -+ defer func() { -+ if rerr != nil { -+ logrus.Warnf("layer(%s) not exist: %s", id, rerr) -+ d.Remove(id) -+ } -+ }() -+ -+ // check if the id directory exist and is valid -+ // check if link file exist and get link string from it -+ // check if symlink file exist -+ // if symlink not exist, create a new one and update link file -+ // any steps failed ,we will return false and remove this id layer -+ _, rerr = os.Stat(d.dir(id)) - if rerr == nil { - lstr, err := ioutil.ReadFile(path.Join(d.dir(id), "link")) - // link is valid --- -2.17.1 - diff --git a/patch/0060-debug-Add-check-when-execute-docker-cp-export.patch b/patch/0060-debug-Add-check-when-execute-docker-cp-export.patch deleted file mode 100644 index 673d47a..0000000 --- a/patch/0060-debug-Add-check-when-execute-docker-cp-export.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 42d1e785f2343323822db35966412fdcfce87989 Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Fri, 18 Jan 2019 15:55:51 +0800 -Subject: [PATCH 060/111] debug: Add check when execute docker {cp, - export, diff} - -reason:If a container is in Dead or RemovalInProgress state,it should return err for tip. - -Cherry-pick from docker 1.11.2: -- 903a5de Add check when execute docker {cp, export, diff} - -Change-Id: Idf441bf7d194cc61c618c20c0e6ef8b339e81191 -Signed-off-by: yangshukui -Signed-off-by: zhangyu235 ---- - components/engine/daemon/archive.go | 13 +++++++++++++ - components/engine/daemon/changes.go | 5 +++++ - 2 files changed, 18 insertions(+) - -diff --git a/components/engine/daemon/archive.go b/components/engine/daemon/archive.go -index 9c7971b56e..f1b715d9ae 100644 ---- a/components/engine/daemon/archive.go -+++ b/components/engine/daemon/archive.go -@@ -1,6 +1,7 @@ - package daemon // import "github.com/docker/docker/daemon" - - import ( -+ "fmt" - "io" - "os" - "strings" -@@ -77,6 +78,10 @@ func (daemon *Daemon) ContainerStatPath(name string, path string) (stat *types.C - return nil, err - } - -+ if container.RemovalInProgress || container.Dead { -+ return nil, fmt.Errorf("can't stat file from a container which is dead or marked for removal") -+ } -+ - // Make sure an online file-system operation is permitted. - if err := daemon.isOnlineFSOperationPermitted(container); err != nil { - return nil, errdefs.System(err) -@@ -102,6 +107,10 @@ func (daemon *Daemon) ContainerArchivePath(name string, path string) (content io - return nil, nil, err - } - -+ if container.RemovalInProgress || container.Dead { -+ return nil, nil, fmt.Errorf("can't copy file from a container which is dead or marked for removal") -+ } -+ - // Make sure an online file-system operation is permitted. - if err := daemon.isOnlineFSOperationPermitted(container); err != nil { - return nil, nil, errdefs.System(err) -@@ -130,6 +139,10 @@ func (daemon *Daemon) ContainerExtractToDir(name, path string, copyUIDGID, noOve - return err - } - -+ if container.RemovalInProgress || container.Dead { -+ return fmt.Errorf("can't copy to a container which is dead or marked for removal") -+ } -+ - // Make sure an online file-system operation is permitted. - if err := daemon.isOnlineFSOperationPermitted(container); err != nil { - return errdefs.System(err) -diff --git a/components/engine/daemon/changes.go b/components/engine/daemon/changes.go -index 70b3f6b943..55575a96bd 100644 ---- a/components/engine/daemon/changes.go -+++ b/components/engine/daemon/changes.go -@@ -6,6 +6,7 @@ import ( - "time" - - "github.com/docker/docker/pkg/archive" -+ "fmt" - ) - - // ContainerChanges returns a list of container fs changes -@@ -16,6 +17,10 @@ func (daemon *Daemon) ContainerChanges(name string) ([]archive.Change, error) { - return nil, err - } - -+ if container.RemovalInProgress || container.Dead { -+ return nil, fmt.Errorf("can't diff a container which is dead or marked for removal") -+ } -+ - if runtime.GOOS == "windows" && container.IsRunning() { - return nil, errors.New("Windows does not support diff of a running container") - } --- -2.17.1 - diff --git a/patch/0061-docker-check-seccomp-file-size-max-10M-before.patch b/patch/0061-docker-check-seccomp-file-size-max-10M-before.patch deleted file mode 100644 index 432d9fd..0000000 --- a/patch/0061-docker-check-seccomp-file-size-max-10M-before.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 3b24c397492b921ce00f9786c8f6dd22cf2bb420 Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Fri, 18 Jan 2019 21:31:47 +0800 -Subject: [PATCH 061/111] docker: check seccomp file size(max:10M) - before read into memory - -reason:when seccomp file size is not limited, docker may result in memory OOM - -Cherry-pick from docker 1.11.2: -- 3660784 check seccomp file size(max:10M) before read into memory - -Change-Id: I6289b2e84e5aaf6d876e689c842f9d18acaf6814 -Signed-off-by: xueshaojia -Signed-off-by: zhangyu235 ---- - components/cli/cli/command/container/opts.go | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/components/cli/cli/command/container/opts.go b/components/cli/cli/command/container/opts.go -index 8e07aa77cb..cbbc110f9c 100644 ---- a/components/cli/cli/command/container/opts.go -+++ b/components/cli/cli/command/container/opts.go -@@ -5,6 +5,7 @@ import ( - "encoding/json" - "fmt" - "io/ioutil" -+ "os" - "path" - "regexp" - "strconv" -@@ -27,6 +28,8 @@ var ( - deviceCgroupRuleRegexp = regexp.MustCompile(`^[acb] ([0-9]+|\*):([0-9]+|\*) [rwm]{1,3}$`) - ) - -+const seccompFileMaxSize = 10 * 1024 * 1024 -+ - // containerOptions is a data object with all the options for creating a container - type containerOptions struct { - attach opts.ListOpts -@@ -726,6 +729,11 @@ func parseSecurityOpts(securityOpts []string) ([]string, error) { - } - } - if con[0] == "seccomp" && con[1] != "unconfined" { -+ if fileInfo, err := os.Stat(con[1]); err != nil { -+ return securityOpts, fmt.Errorf("stat seccomp profile (%s) failed: %v", con[1], err) -+ } else if fileInfo.Size() > seccompFileMaxSize { -+ return securityOpts, fmt.Errorf("stat seccomp profile (%s) failed: size exceed limit %dM", con[1], seccompFileMaxSize/1024/1024) -+ } - f, err := ioutil.ReadFile(con[1]) - if err != nil { - return securityOpts, errors.Errorf("opening seccomp profile (%s) failed: %v", con[1], err) --- -2.17.1 - diff --git a/patch/0062-docker-check-file-size-before-reading-envfile.patch b/patch/0062-docker-check-file-size-before-reading-envfile.patch deleted file mode 100644 index c768f16..0000000 --- a/patch/0062-docker-check-file-size-before-reading-envfile.patch +++ /dev/null @@ -1,87 +0,0 @@ -From e065d6675c95e37144284f2ee5af3f7e326f9efe Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Fri, 18 Jan 2019 22:11:29 +0800 -Subject: [PATCH 062/111] docker: check file size before reading - "envfile" and "labelfile", in case OOM - -reason:check file size before reading "envfile" and "labelfile", in case OOM - -Cherry-pick from docker 1.11.2: -- 931660a check file size before reading "envfile" and "labelfile", in case OOM - -Change-Id: I32bc7951565d0e6e720cf7d9f1d53f8709ebc8b3 -Signed-off-by: panwenxiang -Signed-off-by: zhangyu235 ---- - components/cli/cli/command/container/opts.go | 28 +++++++++++++++++--- - 1 file changed, 25 insertions(+), 3 deletions(-) - -diff --git a/components/cli/cli/command/container/opts.go b/components/cli/cli/command/container/opts.go -index cbbc110f9c..a1bf2be79a 100644 ---- a/components/cli/cli/command/container/opts.go -+++ b/components/cli/cli/command/container/opts.go -@@ -28,7 +28,7 @@ var ( - deviceCgroupRuleRegexp = regexp.MustCompile(`^[acb] ([0-9]+|\*):([0-9]+|\*) [rwm]{1,3}$`) - ) - --const seccompFileMaxSize = 10 * 1024 * 1024 -+const fileMaxSize = 10 * 1024 * 1024 - - // containerOptions is a data object with all the options for creating a container - type containerOptions struct { -@@ -435,12 +435,20 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err - } - - // collect all the environment variables for the container -+ err = checkFileSizeValid(copts.envFile.GetAll()) -+ if err != nil { -+ return nil, err -+ } - envVariables, err := opts.ReadKVEnvStrings(copts.envFile.GetAll(), copts.env.GetAll()) - if err != nil { - return nil, err - } - - // collect all the labels for the container -+ err = checkFileSizeValid(copts.envFile.GetAll()) -+ if err != nil { -+ return nil, err -+ } - labels, err := opts.ReadKVStrings(copts.labelsFile.GetAll(), copts.labels.GetAll()) - if err != nil { - return nil, err -@@ -692,6 +700,20 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err - }, nil - } - -+// check file size -+func checkFileSizeValid(files []string) error { -+ for _, ef := range files { -+ fileInfo, err := os.Stat(ef) -+ if err != nil { -+ return err -+ } -+ if fileInfo.Size() > fileMaxSize { -+ return fmt.Errorf("check (%s) file size is %d, size exceed limit %d ", ef, fileInfo.Size(), fileMaxSize) -+ } -+ } -+ return nil -+} -+ - func parsePortOpts(publishOpts []string) ([]string, error) { - optsList := []string{} - for _, publish := range publishOpts { -@@ -731,8 +753,8 @@ func parseSecurityOpts(securityOpts []string) ([]string, error) { - if con[0] == "seccomp" && con[1] != "unconfined" { - if fileInfo, err := os.Stat(con[1]); err != nil { - return securityOpts, fmt.Errorf("stat seccomp profile (%s) failed: %v", con[1], err) -- } else if fileInfo.Size() > seccompFileMaxSize { -- return securityOpts, fmt.Errorf("stat seccomp profile (%s) failed: size exceed limit %dM", con[1], seccompFileMaxSize/1024/1024) -+ } else if fileInfo.Size() > fileMaxSize { -+ return securityOpts, fmt.Errorf("stat seccomp profile (%s) failed: size exceed limit %dM", con[1], fileMaxSize/1024/1024) - } - f, err := ioutil.ReadFile(con[1]) - if err != nil { --- -2.17.1 - diff --git a/patch/0063-test-fix-umask-make-file-mode-failed.patch b/patch/0063-test-fix-umask-make-file-mode-failed.patch deleted file mode 100644 index ff7a378..0000000 --- a/patch/0063-test-fix-umask-make-file-mode-failed.patch +++ /dev/null @@ -1,38 +0,0 @@ -From a683efcf5e14acdd40574edeaed6b293b0536867 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Tue, 15 Jan 2019 10:16:25 +0800 -Subject: [PATCH 063/111] test: fix umask make file mode failed - -reason: set umask to 0022 make sure test added file's mode match expect. - -Change-Id: I258d3d999c82041a16851f438f556746e6477ebf -Signed-off-by: jingrui ---- - components/engine/internal/test/fakecontext/context.go | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/components/engine/internal/test/fakecontext/context.go b/components/engine/internal/test/fakecontext/context.go -index 8b11da207e..24f326b864 100644 ---- a/components/engine/internal/test/fakecontext/context.go -+++ b/components/engine/internal/test/fakecontext/context.go -@@ -6,6 +6,7 @@ import ( - "io/ioutil" - "os" - "path/filepath" -+ "syscall" - - "github.com/docker/docker/internal/test" - "github.com/docker/docker/pkg/archive" -@@ -96,6 +97,9 @@ func (f *Fake) Add(file, content string) error { - } - - func (f *Fake) addFile(file string, content []byte) error { -+ mask := syscall.Umask(0022) -+ defer syscall.Umask(mask) -+ - fp := filepath.Join(f.Dir, filepath.FromSlash(file)) - dirpath := filepath.Dir(fp) - if dirpath != "." { --- -2.17.1 - diff --git a/patch/0066-test-skip-swarm-integration-test.patch b/patch/0066-test-skip-swarm-integration-test.patch deleted file mode 100644 index cece00b..0000000 --- a/patch/0066-test-skip-swarm-integration-test.patch +++ /dev/null @@ -1,2090 +0,0 @@ -From c1e3ed6a8c993370d3ea9e6559cca31f7aab36f3 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Sat, 12 Jan 2019 10:26:48 +0800 -Subject: [PATCH 066/111] test: skip swarm integration test - -reason: drop unsed swarm integration test. - -Change-Id: Ibb0745de970dcc1cd83b2ebf6ba090bc28edde67 -Signed-off-by: jingrui ---- - .../integration-cli/docker_cli_swarm_test.go | 2067 ----------------- - 1 file changed, 2067 deletions(-) - delete mode 100644 components/engine/integration-cli/docker_cli_swarm_test.go - -diff --git a/components/engine/integration-cli/docker_cli_swarm_test.go b/components/engine/integration-cli/docker_cli_swarm_test.go -deleted file mode 100644 -index f6fadcf995..0000000000 ---- a/components/engine/integration-cli/docker_cli_swarm_test.go -+++ /dev/null -@@ -1,2067 +0,0 @@ --// +build !windows -- --package main -- --import ( -- "bytes" -- "context" -- "encoding/json" -- "encoding/pem" -- "fmt" -- "io/ioutil" -- "net/http" -- "net/http/httptest" -- "os" -- "path/filepath" -- "strings" -- "time" -- -- "github.com/cloudflare/cfssl/helpers" -- "github.com/docker/docker/api/types" -- "github.com/docker/docker/api/types/swarm" -- "github.com/docker/docker/integration-cli/checker" -- "github.com/docker/docker/integration-cli/cli" -- "github.com/docker/docker/integration-cli/daemon" -- "github.com/docker/libnetwork/driverapi" -- "github.com/docker/libnetwork/ipamapi" -- remoteipam "github.com/docker/libnetwork/ipams/remote/api" -- "github.com/docker/swarmkit/ca/keyutils" -- "github.com/go-check/check" -- "github.com/vishvananda/netlink" -- "gotest.tools/fs" -- "gotest.tools/icmd" --) -- --func (s *DockerSwarmSuite) TestSwarmUpdate(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- getSpec := func() swarm.Spec { -- sw := d.GetSwarm(c) -- return sw.Spec -- } -- -- out, err := d.Cmd("swarm", "update", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- spec := getSpec() -- c.Assert(spec.CAConfig.NodeCertExpiry, checker.Equals, 30*time.Hour) -- c.Assert(spec.Dispatcher.HeartbeatPeriod, checker.Equals, 11*time.Second) -- -- // setting anything under 30m for cert-expiry is not allowed -- out, err = d.Cmd("swarm", "update", "--cert-expiry", "15m") -- c.Assert(err, checker.NotNil) -- c.Assert(out, checker.Contains, "minimum certificate expiry time") -- spec = getSpec() -- c.Assert(spec.CAConfig.NodeCertExpiry, checker.Equals, 30*time.Hour) -- -- // passing an external CA (this is without starting a root rotation) does not fail -- cli.Docker(cli.Args("swarm", "update", "--external-ca", "protocol=cfssl,url=https://something.org", -- "--external-ca", "protocol=cfssl,url=https://somethingelse.org,cacert=fixtures/https/ca.pem"), -- cli.Daemon(d)).Assert(c, icmd.Success) -- -- expected, err := ioutil.ReadFile("fixtures/https/ca.pem") -- c.Assert(err, checker.IsNil) -- -- spec = getSpec() -- c.Assert(spec.CAConfig.ExternalCAs, checker.HasLen, 2) -- c.Assert(spec.CAConfig.ExternalCAs[0].CACert, checker.Equals, "") -- c.Assert(spec.CAConfig.ExternalCAs[1].CACert, checker.Equals, string(expected)) -- -- // passing an invalid external CA fails -- tempFile := fs.NewFile(c, "testfile", fs.WithContent("fakecert")) -- defer tempFile.Remove() -- -- result := cli.Docker(cli.Args("swarm", "update", -- "--external-ca", fmt.Sprintf("protocol=cfssl,url=https://something.org,cacert=%s", tempFile.Path())), -- cli.Daemon(d)) -- result.Assert(c, icmd.Expected{ -- ExitCode: 125, -- Err: "must be in PEM format", -- }) --} -- --func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) { -- d := s.AddDaemon(c, false, false) -- -- getSpec := func() swarm.Spec { -- sw := d.GetSwarm(c) -- return sw.Spec -- } -- -- // passing an invalid external CA fails -- tempFile := fs.NewFile(c, "testfile", fs.WithContent("fakecert")) -- defer tempFile.Remove() -- -- result := cli.Docker(cli.Args("swarm", "init", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s", -- "--external-ca", fmt.Sprintf("protocol=cfssl,url=https://somethingelse.org,cacert=%s", tempFile.Path())), -- cli.Daemon(d)) -- result.Assert(c, icmd.Expected{ -- ExitCode: 125, -- Err: "must be in PEM format", -- }) -- -- cli.Docker(cli.Args("swarm", "init", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s", -- "--external-ca", "protocol=cfssl,url=https://something.org", -- "--external-ca", "protocol=cfssl,url=https://somethingelse.org,cacert=fixtures/https/ca.pem"), -- cli.Daemon(d)).Assert(c, icmd.Success) -- -- expected, err := ioutil.ReadFile("fixtures/https/ca.pem") -- c.Assert(err, checker.IsNil) -- -- spec := getSpec() -- c.Assert(spec.CAConfig.NodeCertExpiry, checker.Equals, 30*time.Hour) -- c.Assert(spec.Dispatcher.HeartbeatPeriod, checker.Equals, 11*time.Second) -- c.Assert(spec.CAConfig.ExternalCAs, checker.HasLen, 2) -- c.Assert(spec.CAConfig.ExternalCAs[0].CACert, checker.Equals, "") -- c.Assert(spec.CAConfig.ExternalCAs[1].CACert, checker.Equals, string(expected)) -- -- c.Assert(d.SwarmLeave(true), checker.IsNil) -- cli.Docker(cli.Args("swarm", "init"), cli.Daemon(d)).Assert(c, icmd.Success) -- -- spec = getSpec() -- c.Assert(spec.CAConfig.NodeCertExpiry, checker.Equals, 90*24*time.Hour) -- c.Assert(spec.Dispatcher.HeartbeatPeriod, checker.Equals, 5*time.Second) --} -- --func (s *DockerSwarmSuite) TestSwarmInitIPv6(c *check.C) { -- testRequires(c, IPv6) -- d1 := s.AddDaemon(c, false, false) -- cli.Docker(cli.Args("swarm", "init", "--listen-add", "::1"), cli.Daemon(d1)).Assert(c, icmd.Success) -- -- d2 := s.AddDaemon(c, false, false) -- cli.Docker(cli.Args("swarm", "join", "::1"), cli.Daemon(d2)).Assert(c, icmd.Success) -- -- out := cli.Docker(cli.Args("info"), cli.Daemon(d2)).Assert(c, icmd.Success).Combined() -- c.Assert(out, checker.Contains, "Swarm: active") --} -- --func (s *DockerSwarmSuite) TestSwarmInitUnspecifiedAdvertiseAddr(c *check.C) { -- d := s.AddDaemon(c, false, false) -- out, err := d.Cmd("swarm", "init", "--advertise-addr", "0.0.0.0") -- c.Assert(err, checker.NotNil) -- c.Assert(out, checker.Contains, "advertise address must be a non-zero IP address") --} -- --func (s *DockerSwarmSuite) TestSwarmIncompatibleDaemon(c *check.C) { -- // init swarm mode and stop a daemon -- d := s.AddDaemon(c, true, true) -- info := d.SwarmInfo(c) -- c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) -- d.Stop(c) -- -- // start a daemon with --cluster-store and --cluster-advertise -- err := d.StartWithError("--cluster-store=consul://consuladdr:consulport/some/path", "--cluster-advertise=1.1.1.1:2375") -- c.Assert(err, checker.NotNil) -- content, err := d.ReadLogFile() -- c.Assert(err, checker.IsNil) -- c.Assert(string(content), checker.Contains, "--cluster-store and --cluster-advertise daemon configurations are incompatible with swarm mode") -- -- // start a daemon with --live-restore -- err = d.StartWithError("--live-restore") -- c.Assert(err, checker.NotNil) -- content, err = d.ReadLogFile() -- c.Assert(err, checker.IsNil) -- c.Assert(string(content), checker.Contains, "--live-restore daemon configuration is incompatible with swarm mode") -- // restart for teardown -- d.Start(c) --} -- --func (s *DockerSwarmSuite) TestSwarmServiceTemplatingHostname(c *check.C) { -- d := s.AddDaemon(c, true, true) -- hostname, err := d.Cmd("node", "inspect", "--format", "{{.Description.Hostname}}", "self") -- c.Assert(err, checker.IsNil, check.Commentf("%s", hostname)) -- -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "test", "--hostname", "{{.Service.Name}}-{{.Task.Slot}}-{{.Node.Hostname}}", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) -- -- containers := d.ActiveContainers(c) -- out, err = d.Cmd("inspect", "--type", "container", "--format", "{{.Config.Hostname}}", containers[0]) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.Split(out, "\n")[0], checker.Equals, "test-1-"+strings.Split(hostname, "\n")[0], check.Commentf("hostname with templating invalid")) --} -- --// Test case for #24270 --func (s *DockerSwarmSuite) TestSwarmServiceListFilter(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- name1 := "redis-cluster-md5" -- name2 := "redis-cluster" -- name3 := "other-cluster" -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name1, "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name2, "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name3, "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- filter1 := "name=redis-cluster-md5" -- filter2 := "name=redis-cluster" -- -- // We search checker.Contains with `name+" "` to prevent prefix only. -- out, err = d.Cmd("service", "ls", "--filter", filter1) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, name1+" ") -- c.Assert(out, checker.Not(checker.Contains), name2+" ") -- c.Assert(out, checker.Not(checker.Contains), name3+" ") -- -- out, err = d.Cmd("service", "ls", "--filter", filter2) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, name1+" ") -- c.Assert(out, checker.Contains, name2+" ") -- c.Assert(out, checker.Not(checker.Contains), name3+" ") -- -- out, err = d.Cmd("service", "ls") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, name1+" ") -- c.Assert(out, checker.Contains, name2+" ") -- c.Assert(out, checker.Contains, name3+" ") --} -- --func (s *DockerSwarmSuite) TestSwarmNodeListFilter(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("node", "inspect", "--format", "{{ .Description.Hostname }}", "self") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- name := strings.TrimSpace(out) -- -- filter := "name=" + name[:4] -- -- out, err = d.Cmd("node", "ls", "--filter", filter) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, name) -- -- out, err = d.Cmd("node", "ls", "--filter", "name=none") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Not(checker.Contains), name) --} -- --func (s *DockerSwarmSuite) TestSwarmNodeTaskListFilter(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- name := "redis-cluster-md5" -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--replicas=3", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- // make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 3) -- -- filter := "name=redis-cluster" -- -- out, err = d.Cmd("node", "ps", "--filter", filter, "self") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, name+".1") -- c.Assert(out, checker.Contains, name+".2") -- c.Assert(out, checker.Contains, name+".3") -- -- out, err = d.Cmd("node", "ps", "--filter", "name=none", "self") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Not(checker.Contains), name+".1") -- c.Assert(out, checker.Not(checker.Contains), name+".2") -- c.Assert(out, checker.Not(checker.Contains), name+".3") --} -- --// Test case for #25375 --func (s *DockerSwarmSuite) TestSwarmPublishAdd(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- name := "top" -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--label", "x=y", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- out, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- out, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- _, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", "--publish-add", "80:20", name) -- c.Assert(err, checker.NotNil) -- -- out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.EndpointSpec.Ports }}", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "[{ tcp 80 80 ingress}]") --} -- --func (s *DockerSwarmSuite) TestSwarmServiceWithGroup(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- name := "top" -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--user", "root:root", "--group", "wheel", "--group", "audio", "--group", "staff", "--group", "777", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- // make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) -- -- out, err = d.Cmd("ps", "-q") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- container := strings.TrimSpace(out) -- -- out, err = d.Cmd("exec", container, "id") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "uid=0(root) gid=0(root) groups=10(wheel),29(audio),50(staff),777") --} -- --func (s *DockerSwarmSuite) TestSwarmContainerAutoStart(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("network", "create", "--attachable", "-d", "overlay", "foo") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- out, err = d.Cmd("run", "-id", "--restart=always", "--net=foo", "--name=test", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- out, err = d.Cmd("ps", "-q") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- d.Restart(c) -- -- out, err = d.Cmd("ps", "-q") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") --} -- --func (s *DockerSwarmSuite) TestSwarmContainerEndpointOptions(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("network", "create", "--attachable", "-d", "overlay", "foo") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- _, err = d.Cmd("run", "-d", "--net=foo", "--name=first", "--net-alias=first-alias", "busybox:glibc", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- _, err = d.Cmd("run", "-d", "--net=foo", "--name=second", "busybox:glibc", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- _, err = d.Cmd("run", "-d", "--net=foo", "--net-alias=third-alias", "busybox:glibc", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // ping first container and its alias, also ping third and anonymous container by its alias -- _, err = d.Cmd("exec", "second", "ping", "-c", "1", "first") -- c.Assert(err, check.IsNil, check.Commentf("%s", out)) -- _, err = d.Cmd("exec", "second", "ping", "-c", "1", "first-alias") -- c.Assert(err, check.IsNil, check.Commentf("%s", out)) -- _, err = d.Cmd("exec", "second", "ping", "-c", "1", "third-alias") -- c.Assert(err, check.IsNil, check.Commentf("%s", out)) --} -- --func (s *DockerSwarmSuite) TestSwarmContainerAttachByNetworkId(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("network", "create", "--attachable", "-d", "overlay", "testnet") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- networkID := strings.TrimSpace(out) -- -- out, err = d.Cmd("run", "-d", "--net", networkID, "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- cID := strings.TrimSpace(out) -- d.WaitRun(cID) -- -- out, err = d.Cmd("rm", "-f", cID) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- out, err = d.Cmd("network", "rm", "testnet") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- checkNetwork := func(*check.C) (interface{}, check.CommentInterface) { -- out, err := d.Cmd("network", "ls") -- c.Assert(err, checker.IsNil) -- return out, nil -- } -- -- waitAndAssert(c, 3*time.Second, checkNetwork, checker.Not(checker.Contains), "testnet") --} -- --func (s *DockerSwarmSuite) TestOverlayAttachable(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("network", "create", "-d", "overlay", "--attachable", "ovnet") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // validate attachable -- out, err = d.Cmd("network", "inspect", "--format", "{{json .Attachable}}", "ovnet") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "true") -- -- // validate containers can attache to this overlay network -- out, err = d.Cmd("run", "-d", "--network", "ovnet", "--name", "c1", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // redo validation, there was a bug that the value of attachable changes after -- // containers attach to the network -- out, err = d.Cmd("network", "inspect", "--format", "{{json .Attachable}}", "ovnet") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "true") --} -- --func (s *DockerSwarmSuite) TestOverlayAttachableOnSwarmLeave(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // Create an attachable swarm network -- nwName := "attovl" -- out, err := d.Cmd("network", "create", "-d", "overlay", "--attachable", nwName) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // Connect a container to the network -- out, err = d.Cmd("run", "-d", "--network", nwName, "--name", "c1", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // Leave the swarm -- err = d.SwarmLeave(true) -- c.Assert(err, checker.IsNil) -- -- // Check the container is disconnected -- out, err = d.Cmd("inspect", "c1", "--format", "{{.NetworkSettings.Networks."+nwName+"}}") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "") -- -- // Check the network is gone -- out, err = d.Cmd("network", "ls", "--format", "{{.Name}}") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Not(checker.Contains), nwName) --} -- --func (s *DockerSwarmSuite) TestOverlayAttachableReleaseResourcesOnFailure(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // Create attachable network -- out, err := d.Cmd("network", "create", "-d", "overlay", "--attachable", "--subnet", "10.10.9.0/24", "ovnet") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // Attach a container with specific IP -- out, err = d.Cmd("run", "-d", "--network", "ovnet", "--name", "c1", "--ip", "10.10.9.33", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // Attempt to attach another container with same IP, must fail -- out, err = d.Cmd("run", "-d", "--network", "ovnet", "--name", "c2", "--ip", "10.10.9.33", "busybox", "top") -- c.Assert(err, checker.NotNil, check.Commentf("%s", out)) -- -- // Remove first container -- out, err = d.Cmd("rm", "-f", "c1") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // Verify the network can be removed, no phantom network attachment task left over -- out, err = d.Cmd("network", "rm", "ovnet") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) --} -- --func (s *DockerSwarmSuite) TestSwarmIngressNetwork(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // Ingress network can be removed -- removeNetwork := func(name string) *icmd.Result { -- return cli.Docker( -- cli.Args("-H", d.Sock(), "network", "rm", name), -- cli.WithStdin(strings.NewReader("Y"))) -- } -- -- result := removeNetwork("ingress") -- result.Assert(c, icmd.Success) -- -- // And recreated -- out, err := d.Cmd("network", "create", "-d", "overlay", "--ingress", "new-ingress") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // But only one is allowed -- out, err = d.Cmd("network", "create", "-d", "overlay", "--ingress", "another-ingress") -- c.Assert(err, checker.NotNil) -- c.Assert(strings.TrimSpace(out), checker.Contains, "is already present") -- -- // It cannot be removed if it is being used -- out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "srv1", "-p", "9000:8000", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- result = removeNetwork("new-ingress") -- result.Assert(c, icmd.Expected{ -- ExitCode: 1, -- Err: "ingress network cannot be removed because service", -- }) -- -- // But it can be removed once no more services depend on it -- out, err = d.Cmd("service", "update", "--detach", "--publish-rm", "9000:8000", "srv1") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- result = removeNetwork("new-ingress") -- result.Assert(c, icmd.Success) -- -- // A service which needs the ingress network cannot be created if no ingress is present -- out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "srv2", "-p", "500:500", "busybox", "top") -- c.Assert(err, checker.NotNil) -- c.Assert(strings.TrimSpace(out), checker.Contains, "no ingress network is present") -- -- // An existing service cannot be updated to use the ingress nw if the nw is not present -- out, err = d.Cmd("service", "update", "--detach", "--publish-add", "9000:8000", "srv1") -- c.Assert(err, checker.NotNil) -- c.Assert(strings.TrimSpace(out), checker.Contains, "no ingress network is present") -- -- // But services which do not need routing mesh can be created regardless -- out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "srv3", "--endpoint-mode", "dnsrr", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) --} -- --func (s *DockerSwarmSuite) TestSwarmCreateServiceWithNoIngressNetwork(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // Remove ingress network -- result := cli.Docker( -- cli.Args("-H", d.Sock(), "network", "rm", "ingress"), -- cli.WithStdin(strings.NewReader("Y"))) -- result.Assert(c, icmd.Success) -- -- // Create a overlay network and launch a service on it -- // Make sure nothing panics because ingress network is missing -- out, err := d.Cmd("network", "create", "-d", "overlay", "another-network") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "srv4", "--network", "another-network", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) --} -- --// Test case for #24108, also the case from: --// https://github.com/docker/docker/pull/24620#issuecomment-233715656 --func (s *DockerSwarmSuite) TestSwarmTaskListFilter(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- name := "redis-cluster-md5" -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--replicas=3", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- filter := "name=redis-cluster" -- -- checkNumTasks := func(*check.C) (interface{}, check.CommentInterface) { -- out, err := d.Cmd("service", "ps", "--filter", filter, name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- return len(strings.Split(out, "\n")) - 2, nil // includes header and nl in last line -- } -- -- // wait until all tasks have been created -- waitAndAssert(c, defaultReconciliationTimeout, checkNumTasks, checker.Equals, 3) -- -- out, err = d.Cmd("service", "ps", "--filter", filter, name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, name+".1") -- c.Assert(out, checker.Contains, name+".2") -- c.Assert(out, checker.Contains, name+".3") -- -- out, err = d.Cmd("service", "ps", "--filter", "name="+name+".1", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, name+".1") -- c.Assert(out, checker.Not(checker.Contains), name+".2") -- c.Assert(out, checker.Not(checker.Contains), name+".3") -- -- out, err = d.Cmd("service", "ps", "--filter", "name=none", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Not(checker.Contains), name+".1") -- c.Assert(out, checker.Not(checker.Contains), name+".2") -- c.Assert(out, checker.Not(checker.Contains), name+".3") -- -- name = "redis-cluster-sha1" -- out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--mode=global", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- waitAndAssert(c, defaultReconciliationTimeout, checkNumTasks, checker.Equals, 1) -- -- filter = "name=redis-cluster" -- out, err = d.Cmd("service", "ps", "--filter", filter, name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, name) -- -- out, err = d.Cmd("service", "ps", "--filter", "name="+name, name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, name) -- -- out, err = d.Cmd("service", "ps", "--filter", "name=none", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Not(checker.Contains), name) --} -- --func (s *DockerSwarmSuite) TestPsListContainersFilterIsTask(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // Create a bare container -- out, err := d.Cmd("run", "-d", "--name=bare-container", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- bareID := strings.TrimSpace(out)[:12] -- // Create a service -- name := "busybox-top" -- out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- // make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckServiceRunningTasks(name), checker.Equals, 1) -- -- // Filter non-tasks -- out, err = d.Cmd("ps", "-a", "-q", "--filter=is-task=false") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- psOut := strings.TrimSpace(out) -- c.Assert(psOut, checker.Equals, bareID, check.Commentf("Expected id %s, got %s for is-task label, output %q", bareID, psOut, out)) -- -- // Filter tasks -- out, err = d.Cmd("ps", "-a", "-q", "--filter=is-task=true") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- lines := strings.Split(strings.Trim(out, "\n "), "\n") -- c.Assert(lines, checker.HasLen, 1) -- c.Assert(lines[0], checker.Not(checker.Equals), bareID, check.Commentf("Expected not %s, but got it for is-task label, output %q", bareID, out)) --} -- --const globalNetworkPlugin = "global-network-plugin" --const globalIPAMPlugin = "global-ipam-plugin" -- --func setupRemoteGlobalNetworkPlugin(c *check.C, mux *http.ServeMux, url, netDrv, ipamDrv string) { -- -- mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) { -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- fmt.Fprintf(w, `{"Implements": ["%s", "%s"]}`, driverapi.NetworkPluginEndpointType, ipamapi.PluginEndpointType) -- }) -- -- // Network driver implementation -- mux.HandleFunc(fmt.Sprintf("/%s.GetCapabilities", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- fmt.Fprintf(w, `{"Scope":"global"}`) -- }) -- -- mux.HandleFunc(fmt.Sprintf("/%s.AllocateNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- err := json.NewDecoder(r.Body).Decode(&remoteDriverNetworkRequest) -- if err != nil { -- http.Error(w, "Unable to decode JSON payload: "+err.Error(), http.StatusBadRequest) -- return -- } -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- fmt.Fprintf(w, "null") -- }) -- -- mux.HandleFunc(fmt.Sprintf("/%s.FreeNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- fmt.Fprintf(w, "null") -- }) -- -- mux.HandleFunc(fmt.Sprintf("/%s.CreateNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- err := json.NewDecoder(r.Body).Decode(&remoteDriverNetworkRequest) -- if err != nil { -- http.Error(w, "Unable to decode JSON payload: "+err.Error(), http.StatusBadRequest) -- return -- } -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- fmt.Fprintf(w, "null") -- }) -- -- mux.HandleFunc(fmt.Sprintf("/%s.DeleteNetwork", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- fmt.Fprintf(w, "null") -- }) -- -- mux.HandleFunc(fmt.Sprintf("/%s.CreateEndpoint", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- fmt.Fprintf(w, `{"Interface":{"MacAddress":"a0:b1:c2:d3:e4:f5"}}`) -- }) -- -- mux.HandleFunc(fmt.Sprintf("/%s.Join", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- -- veth := &netlink.Veth{ -- LinkAttrs: netlink.LinkAttrs{Name: "randomIfName", TxQLen: 0}, PeerName: "cnt0"} -- if err := netlink.LinkAdd(veth); err != nil { -- fmt.Fprintf(w, `{"Error":"failed to add veth pair: `+err.Error()+`"}`) -- } else { -- fmt.Fprintf(w, `{"InterfaceName":{ "SrcName":"cnt0", "DstPrefix":"veth"}}`) -- } -- }) -- -- mux.HandleFunc(fmt.Sprintf("/%s.Leave", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- fmt.Fprintf(w, "null") -- }) -- -- mux.HandleFunc(fmt.Sprintf("/%s.DeleteEndpoint", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- if link, err := netlink.LinkByName("cnt0"); err == nil { -- netlink.LinkDel(link) -- } -- fmt.Fprintf(w, "null") -- }) -- -- // IPAM Driver implementation -- var ( -- poolRequest remoteipam.RequestPoolRequest -- poolReleaseReq remoteipam.ReleasePoolRequest -- addressRequest remoteipam.RequestAddressRequest -- addressReleaseReq remoteipam.ReleaseAddressRequest -- lAS = "localAS" -- gAS = "globalAS" -- pool = "172.28.0.0/16" -- poolID = lAS + "/" + pool -- gw = "172.28.255.254/16" -- ) -- -- mux.HandleFunc(fmt.Sprintf("/%s.GetDefaultAddressSpaces", ipamapi.PluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- fmt.Fprintf(w, `{"LocalDefaultAddressSpace":"`+lAS+`", "GlobalDefaultAddressSpace": "`+gAS+`"}`) -- }) -- -- mux.HandleFunc(fmt.Sprintf("/%s.RequestPool", ipamapi.PluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- err := json.NewDecoder(r.Body).Decode(&poolRequest) -- if err != nil { -- http.Error(w, "Unable to decode JSON payload: "+err.Error(), http.StatusBadRequest) -- return -- } -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- if poolRequest.AddressSpace != lAS && poolRequest.AddressSpace != gAS { -- fmt.Fprintf(w, `{"Error":"Unknown address space in pool request: `+poolRequest.AddressSpace+`"}`) -- } else if poolRequest.Pool != "" && poolRequest.Pool != pool { -- fmt.Fprintf(w, `{"Error":"Cannot handle explicit pool requests yet"}`) -- } else { -- fmt.Fprintf(w, `{"PoolID":"`+poolID+`", "Pool":"`+pool+`"}`) -- } -- }) -- -- mux.HandleFunc(fmt.Sprintf("/%s.RequestAddress", ipamapi.PluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- err := json.NewDecoder(r.Body).Decode(&addressRequest) -- if err != nil { -- http.Error(w, "Unable to decode JSON payload: "+err.Error(), http.StatusBadRequest) -- return -- } -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- // make sure libnetwork is now querying on the expected pool id -- if addressRequest.PoolID != poolID { -- fmt.Fprintf(w, `{"Error":"unknown pool id"}`) -- } else if addressRequest.Address != "" { -- fmt.Fprintf(w, `{"Error":"Cannot handle explicit address requests yet"}`) -- } else { -- fmt.Fprintf(w, `{"Address":"`+gw+`"}`) -- } -- }) -- -- mux.HandleFunc(fmt.Sprintf("/%s.ReleaseAddress", ipamapi.PluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- err := json.NewDecoder(r.Body).Decode(&addressReleaseReq) -- if err != nil { -- http.Error(w, "Unable to decode JSON payload: "+err.Error(), http.StatusBadRequest) -- return -- } -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- // make sure libnetwork is now asking to release the expected address from the expected poolid -- if addressRequest.PoolID != poolID { -- fmt.Fprintf(w, `{"Error":"unknown pool id"}`) -- } else if addressReleaseReq.Address != gw { -- fmt.Fprintf(w, `{"Error":"unknown address"}`) -- } else { -- fmt.Fprintf(w, "null") -- } -- }) -- -- mux.HandleFunc(fmt.Sprintf("/%s.ReleasePool", ipamapi.PluginEndpointType), func(w http.ResponseWriter, r *http.Request) { -- err := json.NewDecoder(r.Body).Decode(&poolReleaseReq) -- if err != nil { -- http.Error(w, "Unable to decode JSON payload: "+err.Error(), http.StatusBadRequest) -- return -- } -- w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") -- // make sure libnetwork is now asking to release the expected poolid -- if addressRequest.PoolID != poolID { -- fmt.Fprintf(w, `{"Error":"unknown pool id"}`) -- } else { -- fmt.Fprintf(w, "null") -- } -- }) -- -- err := os.MkdirAll("/etc/docker/plugins", 0755) -- c.Assert(err, checker.IsNil) -- -- fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", netDrv) -- err = ioutil.WriteFile(fileName, []byte(url), 0644) -- c.Assert(err, checker.IsNil) -- -- ipamFileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", ipamDrv) -- err = ioutil.WriteFile(ipamFileName, []byte(url), 0644) -- c.Assert(err, checker.IsNil) --} -- --func (s *DockerSwarmSuite) TestSwarmNetworkPlugin(c *check.C) { -- mux := http.NewServeMux() -- s.server = httptest.NewServer(mux) -- c.Assert(s.server, check.NotNil) // check that HTTP server has started -- setupRemoteGlobalNetworkPlugin(c, mux, s.server.URL, globalNetworkPlugin, globalIPAMPlugin) -- defer func() { -- s.server.Close() -- err := os.RemoveAll("/etc/docker/plugins") -- c.Assert(err, checker.IsNil) -- }() -- -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("network", "create", "-d", globalNetworkPlugin, "foo") -- c.Assert(err, checker.NotNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, "not supported in swarm mode") --} -- --// Test case for #24712 --func (s *DockerSwarmSuite) TestSwarmServiceEnvFile(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- path := filepath.Join(d.Folder, "env.txt") -- err := ioutil.WriteFile(path, []byte("VAR1=A\nVAR2=A\n"), 0644) -- c.Assert(err, checker.IsNil) -- -- name := "worker" -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--env-file", path, "--env", "VAR1=B", "--env", "VAR1=C", "--env", "VAR2=", "--env", "VAR2", "--name", name, "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- // The complete env is [VAR1=A VAR2=A VAR1=B VAR1=C VAR2= VAR2] and duplicates will be removed => [VAR1=C VAR2] -- out, err = d.Cmd("inspect", "--format", "{{ .Spec.TaskTemplate.ContainerSpec.Env }}", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, "[VAR1=C VAR2]") --} -- --func (s *DockerSwarmSuite) TestSwarmServiceTTY(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- name := "top" -- -- ttyCheck := "if [ -t 0 ]; then echo TTY > /status && top; else echo none > /status && top; fi" -- -- // Without --tty -- expectedOutput := "none" -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox", "sh", "-c", ttyCheck) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // Make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) -- -- // We need to get the container id. -- out, err = d.Cmd("ps", "-q", "--no-trunc") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- id := strings.TrimSpace(out) -- -- out, err = d.Cmd("exec", id, "cat", "/status") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out)) -- -- // Remove service -- out, err = d.Cmd("service", "rm", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- // Make sure container has been destroyed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 0) -- -- // With --tty -- expectedOutput = "TTY" -- out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--tty", "busybox", "sh", "-c", ttyCheck) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // Make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) -- -- // We need to get the container id. -- out, err = d.Cmd("ps", "-q", "--no-trunc") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- id = strings.TrimSpace(out) -- -- out, err = d.Cmd("exec", id, "cat", "/status") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out)) --} -- --func (s *DockerSwarmSuite) TestSwarmServiceTTYUpdate(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // Create a service -- name := "top" -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // Make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) -- -- out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.TaskTemplate.ContainerSpec.TTY }}", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "false") -- -- out, err = d.Cmd("service", "update", "--detach", "--tty", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.TaskTemplate.ContainerSpec.TTY }}", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "true") --} -- --func (s *DockerSwarmSuite) TestSwarmServiceNetworkUpdate(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- result := icmd.RunCmd(d.Command("network", "create", "-d", "overlay", "foo")) -- result.Assert(c, icmd.Success) -- fooNetwork := strings.TrimSpace(string(result.Combined())) -- -- result = icmd.RunCmd(d.Command("network", "create", "-d", "overlay", "bar")) -- result.Assert(c, icmd.Success) -- barNetwork := strings.TrimSpace(string(result.Combined())) -- -- result = icmd.RunCmd(d.Command("network", "create", "-d", "overlay", "baz")) -- result.Assert(c, icmd.Success) -- bazNetwork := strings.TrimSpace(string(result.Combined())) -- -- // Create a service -- name := "top" -- result = icmd.RunCmd(d.Command("service", "create", "--detach", "--no-resolve-image", "--network", "foo", "--network", "bar", "--name", name, "busybox", "top")) -- result.Assert(c, icmd.Success) -- -- // Make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskNetworks, checker.DeepEquals, -- map[string]int{fooNetwork: 1, barNetwork: 1}) -- -- // Remove a network -- result = icmd.RunCmd(d.Command("service", "update", "--detach", "--network-rm", "foo", name)) -- result.Assert(c, icmd.Success) -- -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskNetworks, checker.DeepEquals, -- map[string]int{barNetwork: 1}) -- -- // Add a network -- result = icmd.RunCmd(d.Command("service", "update", "--detach", "--network-add", "baz", name)) -- result.Assert(c, icmd.Success) -- -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckRunningTaskNetworks, checker.DeepEquals, -- map[string]int{barNetwork: 1, bazNetwork: 1}) --} -- --func (s *DockerSwarmSuite) TestDNSConfig(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // Create a service -- name := "top" -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--dns=1.2.3.4", "--dns-search=example.com", "--dns-option=timeout:3", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // Make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) -- -- // We need to get the container id. -- out, err = d.Cmd("ps", "-a", "-q", "--no-trunc") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- id := strings.TrimSpace(out) -- -- // Compare against expected output. -- expectedOutput1 := "nameserver 1.2.3.4" -- expectedOutput2 := "search example.com" -- expectedOutput3 := "options timeout:3" -- out, err = d.Cmd("exec", id, "cat", "/etc/resolv.conf") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, expectedOutput1, check.Commentf("Expected '%s', but got %q", expectedOutput1, out)) -- c.Assert(out, checker.Contains, expectedOutput2, check.Commentf("Expected '%s', but got %q", expectedOutput2, out)) -- c.Assert(out, checker.Contains, expectedOutput3, check.Commentf("Expected '%s', but got %q", expectedOutput3, out)) --} -- --func (s *DockerSwarmSuite) TestDNSConfigUpdate(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // Create a service -- name := "top" -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // Make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) -- -- out, err = d.Cmd("service", "update", "--detach", "--dns-add=1.2.3.4", "--dns-search-add=example.com", "--dns-option-add=timeout:3", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.TaskTemplate.ContainerSpec.DNSConfig }}", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "{[1.2.3.4] [example.com] [timeout:3]}") --} -- --func getNodeStatus(c *check.C, d *daemon.Daemon) swarm.LocalNodeState { -- info := d.SwarmInfo(c) -- return info.LocalNodeState --} -- --func checkKeyIsEncrypted(d *daemon.Daemon) func(*check.C) (interface{}, check.CommentInterface) { -- return func(c *check.C) (interface{}, check.CommentInterface) { -- keyBytes, err := ioutil.ReadFile(filepath.Join(d.Folder, "root", "swarm", "certificates", "swarm-node.key")) -- if err != nil { -- return fmt.Errorf("error reading key: %v", err), nil -- } -- -- keyBlock, _ := pem.Decode(keyBytes) -- if keyBlock == nil { -- return fmt.Errorf("invalid PEM-encoded private key"), nil -- } -- -- return keyutils.IsEncryptedPEMBlock(keyBlock), nil -- } --} -- --func checkSwarmLockedToUnlocked(c *check.C, d *daemon.Daemon, unlockKey string) { -- // Wait for the PEM file to become unencrypted -- waitAndAssert(c, defaultReconciliationTimeout, checkKeyIsEncrypted(d), checker.Equals, false) -- -- d.Restart(c) -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateActive) --} -- --func checkSwarmUnlockedToLocked(c *check.C, d *daemon.Daemon) { -- // Wait for the PEM file to become encrypted -- waitAndAssert(c, defaultReconciliationTimeout, checkKeyIsEncrypted(d), checker.Equals, true) -- -- d.Restart(c) -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateLocked) --} -- --func (s *DockerSwarmSuite) TestUnlockEngineAndUnlockedSwarm(c *check.C) { -- d := s.AddDaemon(c, false, false) -- -- // unlocking a normal engine should return an error - it does not even ask for the key -- cmd := d.Command("swarm", "unlock") -- result := icmd.RunCmd(cmd) -- result.Assert(c, icmd.Expected{ -- ExitCode: 1, -- }) -- c.Assert(result.Combined(), checker.Contains, "Error: This node is not part of a swarm") -- c.Assert(result.Combined(), checker.Not(checker.Contains), "Please enter unlock key") -- -- out, err := d.Cmd("swarm", "init") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // unlocking an unlocked swarm should return an error - it does not even ask for the key -- cmd = d.Command("swarm", "unlock") -- result = icmd.RunCmd(cmd) -- result.Assert(c, icmd.Expected{ -- ExitCode: 1, -- }) -- c.Assert(result.Combined(), checker.Contains, "Error: swarm is not locked") -- c.Assert(result.Combined(), checker.Not(checker.Contains), "Please enter unlock key") --} -- --func (s *DockerSwarmSuite) TestSwarmInitLocked(c *check.C) { -- d := s.AddDaemon(c, false, false) -- -- outs, err := d.Cmd("swarm", "init", "--autolock") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- -- c.Assert(outs, checker.Contains, "docker swarm unlock") -- -- var unlockKey string -- for _, line := range strings.Split(outs, "\n") { -- if strings.Contains(line, "SWMKEY") { -- unlockKey = strings.TrimSpace(line) -- break -- } -- } -- -- c.Assert(unlockKey, checker.Not(checker.Equals), "") -- -- outs, err = d.Cmd("swarm", "unlock-key", "-q") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- c.Assert(outs, checker.Equals, unlockKey+"\n") -- -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateActive) -- -- // It starts off locked -- d.Restart(c) -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateLocked) -- -- cmd := d.Command("swarm", "unlock") -- cmd.Stdin = bytes.NewBufferString("wrong-secret-key") -- icmd.RunCmd(cmd).Assert(c, icmd.Expected{ -- ExitCode: 1, -- Err: "invalid key", -- }) -- -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateLocked) -- -- cmd = d.Command("swarm", "unlock") -- cmd.Stdin = bytes.NewBufferString(unlockKey) -- icmd.RunCmd(cmd).Assert(c, icmd.Success) -- -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateActive) -- -- outs, err = d.Cmd("node", "ls") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- c.Assert(outs, checker.Not(checker.Contains), "Swarm is encrypted and needs to be unlocked") -- -- outs, err = d.Cmd("swarm", "update", "--autolock=false") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- -- checkSwarmLockedToUnlocked(c, d, unlockKey) -- -- outs, err = d.Cmd("node", "ls") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- c.Assert(outs, checker.Not(checker.Contains), "Swarm is encrypted and needs to be unlocked") --} -- --func (s *DockerSwarmSuite) TestSwarmLeaveLocked(c *check.C) { -- d := s.AddDaemon(c, false, false) -- -- outs, err := d.Cmd("swarm", "init", "--autolock") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- -- // It starts off locked -- d.Restart(c, "--swarm-default-advertise-addr=lo") -- -- info := d.SwarmInfo(c) -- c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateLocked) -- -- outs, _ = d.Cmd("node", "ls") -- c.Assert(outs, checker.Contains, "Swarm is encrypted and needs to be unlocked") -- -- // `docker swarm leave` a locked swarm without --force will return an error -- outs, _ = d.Cmd("swarm", "leave") -- c.Assert(outs, checker.Contains, "Swarm is encrypted and locked.") -- -- // It is OK for user to leave a locked swarm with --force -- outs, err = d.Cmd("swarm", "leave", "--force") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- -- info = d.SwarmInfo(c) -- c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive) -- -- outs, err = d.Cmd("swarm", "init") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- -- info = d.SwarmInfo(c) -- c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) --} -- --func (s *DockerSwarmSuite) TestSwarmLockUnlockCluster(c *check.C) { -- d1 := s.AddDaemon(c, true, true) -- d2 := s.AddDaemon(c, true, true) -- d3 := s.AddDaemon(c, true, true) -- -- // they start off unlocked -- d2.Restart(c) -- c.Assert(getNodeStatus(c, d2), checker.Equals, swarm.LocalNodeStateActive) -- -- // stop this one so it does not get autolock info -- d2.Stop(c) -- -- // enable autolock -- outs, err := d1.Cmd("swarm", "update", "--autolock") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- -- c.Assert(outs, checker.Contains, "docker swarm unlock") -- -- var unlockKey string -- for _, line := range strings.Split(outs, "\n") { -- if strings.Contains(line, "SWMKEY") { -- unlockKey = strings.TrimSpace(line) -- break -- } -- } -- -- c.Assert(unlockKey, checker.Not(checker.Equals), "") -- -- outs, err = d1.Cmd("swarm", "unlock-key", "-q") -- c.Assert(err, checker.IsNil) -- c.Assert(outs, checker.Equals, unlockKey+"\n") -- -- // The ones that got the cluster update should be set to locked -- for _, d := range []*daemon.Daemon{d1, d3} { -- checkSwarmUnlockedToLocked(c, d) -- -- cmd := d.Command("swarm", "unlock") -- cmd.Stdin = bytes.NewBufferString(unlockKey) -- icmd.RunCmd(cmd).Assert(c, icmd.Success) -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateActive) -- } -- -- // d2 never got the cluster update, so it is still set to unlocked -- d2.Start(c) -- c.Assert(getNodeStatus(c, d2), checker.Equals, swarm.LocalNodeStateActive) -- -- // d2 is now set to lock -- checkSwarmUnlockedToLocked(c, d2) -- -- // leave it locked, and set the cluster to no longer autolock -- outs, err = d1.Cmd("swarm", "update", "--autolock=false") -- c.Assert(err, checker.IsNil, check.Commentf("out: %v", outs)) -- -- // the ones that got the update are now set to unlocked -- for _, d := range []*daemon.Daemon{d1, d3} { -- checkSwarmLockedToUnlocked(c, d, unlockKey) -- } -- -- // d2 still locked -- c.Assert(getNodeStatus(c, d2), checker.Equals, swarm.LocalNodeStateLocked) -- -- // unlock it -- cmd := d2.Command("swarm", "unlock") -- cmd.Stdin = bytes.NewBufferString(unlockKey) -- icmd.RunCmd(cmd).Assert(c, icmd.Success) -- c.Assert(getNodeStatus(c, d2), checker.Equals, swarm.LocalNodeStateActive) -- -- // once it's caught up, d2 is set to not be locked -- checkSwarmLockedToUnlocked(c, d2, unlockKey) -- -- // managers who join now are never set to locked in the first place -- d4 := s.AddDaemon(c, true, true) -- d4.Restart(c) -- c.Assert(getNodeStatus(c, d4), checker.Equals, swarm.LocalNodeStateActive) --} -- --func (s *DockerSwarmSuite) TestSwarmJoinPromoteLocked(c *check.C) { -- d1 := s.AddDaemon(c, true, true) -- -- // enable autolock -- outs, err := d1.Cmd("swarm", "update", "--autolock") -- c.Assert(err, checker.IsNil, check.Commentf("out: %v", outs)) -- -- c.Assert(outs, checker.Contains, "docker swarm unlock") -- -- var unlockKey string -- for _, line := range strings.Split(outs, "\n") { -- if strings.Contains(line, "SWMKEY") { -- unlockKey = strings.TrimSpace(line) -- break -- } -- } -- -- c.Assert(unlockKey, checker.Not(checker.Equals), "") -- -- outs, err = d1.Cmd("swarm", "unlock-key", "-q") -- c.Assert(err, checker.IsNil) -- c.Assert(outs, checker.Equals, unlockKey+"\n") -- -- // joined workers start off unlocked -- d2 := s.AddDaemon(c, true, false) -- d2.Restart(c) -- c.Assert(getNodeStatus(c, d2), checker.Equals, swarm.LocalNodeStateActive) -- -- // promote worker -- outs, err = d1.Cmd("node", "promote", d2.NodeID()) -- c.Assert(err, checker.IsNil) -- c.Assert(outs, checker.Contains, "promoted to a manager in the swarm") -- -- // join new manager node -- d3 := s.AddDaemon(c, true, true) -- -- // both new nodes are locked -- for _, d := range []*daemon.Daemon{d2, d3} { -- checkSwarmUnlockedToLocked(c, d) -- -- cmd := d.Command("swarm", "unlock") -- cmd.Stdin = bytes.NewBufferString(unlockKey) -- icmd.RunCmd(cmd).Assert(c, icmd.Success) -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateActive) -- } -- -- // demote manager back to worker - workers are not locked -- outs, err = d1.Cmd("node", "demote", d3.NodeID()) -- c.Assert(err, checker.IsNil) -- c.Assert(outs, checker.Contains, "demoted in the swarm") -- -- // Wait for it to actually be demoted, for the key and cert to be replaced. -- // Then restart and assert that the node is not locked. If we don't wait for the cert -- // to be replaced, then the node still has the manager TLS key which is still locked -- // (because we never want a manager TLS key to be on disk unencrypted if the cluster -- // is set to autolock) -- waitAndAssert(c, defaultReconciliationTimeout, d3.CheckControlAvailable, checker.False) -- waitAndAssert(c, defaultReconciliationTimeout, func(c *check.C) (interface{}, check.CommentInterface) { -- certBytes, err := ioutil.ReadFile(filepath.Join(d3.Folder, "root", "swarm", "certificates", "swarm-node.crt")) -- if err != nil { -- return "", check.Commentf("error: %v", err) -- } -- certs, err := helpers.ParseCertificatesPEM(certBytes) -- if err == nil && len(certs) > 0 && len(certs[0].Subject.OrganizationalUnit) > 0 { -- return certs[0].Subject.OrganizationalUnit[0], nil -- } -- return "", check.Commentf("could not get organizational unit from certificate") -- }, checker.Equals, "swarm-worker") -- -- // by now, it should *never* be locked on restart -- d3.Restart(c) -- c.Assert(getNodeStatus(c, d3), checker.Equals, swarm.LocalNodeStateActive) --} -- --func (s *DockerSwarmSuite) TestSwarmRotateUnlockKey(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- outs, err := d.Cmd("swarm", "update", "--autolock") -- c.Assert(err, checker.IsNil, check.Commentf("out: %v", outs)) -- -- c.Assert(outs, checker.Contains, "docker swarm unlock") -- -- var unlockKey string -- for _, line := range strings.Split(outs, "\n") { -- if strings.Contains(line, "SWMKEY") { -- unlockKey = strings.TrimSpace(line) -- break -- } -- } -- -- c.Assert(unlockKey, checker.Not(checker.Equals), "") -- -- outs, err = d.Cmd("swarm", "unlock-key", "-q") -- c.Assert(err, checker.IsNil) -- c.Assert(outs, checker.Equals, unlockKey+"\n") -- -- // Rotate multiple times -- for i := 0; i != 3; i++ { -- outs, err = d.Cmd("swarm", "unlock-key", "-q", "--rotate") -- c.Assert(err, checker.IsNil, check.Commentf("out: %v", outs)) -- // Strip \n -- newUnlockKey := outs[:len(outs)-1] -- c.Assert(newUnlockKey, checker.Not(checker.Equals), "") -- c.Assert(newUnlockKey, checker.Not(checker.Equals), unlockKey) -- -- d.Restart(c) -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateLocked) -- -- outs, _ = d.Cmd("node", "ls") -- c.Assert(outs, checker.Contains, "Swarm is encrypted and needs to be unlocked") -- -- cmd := d.Command("swarm", "unlock") -- cmd.Stdin = bytes.NewBufferString(unlockKey) -- result := icmd.RunCmd(cmd) -- -- if result.Error == nil { -- // On occasion, the daemon may not have finished -- // rotating the KEK before restarting. The test is -- // intentionally written to explore this behavior. -- // When this happens, unlocking with the old key will -- // succeed. If we wait for the rotation to happen and -- // restart again, the new key should be required this -- // time. -- -- time.Sleep(3 * time.Second) -- -- d.Restart(c) -- -- cmd = d.Command("swarm", "unlock") -- cmd.Stdin = bytes.NewBufferString(unlockKey) -- result = icmd.RunCmd(cmd) -- } -- result.Assert(c, icmd.Expected{ -- ExitCode: 1, -- Err: "invalid key", -- }) -- -- outs, _ = d.Cmd("node", "ls") -- c.Assert(outs, checker.Contains, "Swarm is encrypted and needs to be unlocked") -- -- cmd = d.Command("swarm", "unlock") -- cmd.Stdin = bytes.NewBufferString(newUnlockKey) -- icmd.RunCmd(cmd).Assert(c, icmd.Success) -- -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateActive) -- -- outs, err = d.Cmd("node", "ls") -- c.Assert(err, checker.IsNil) -- c.Assert(outs, checker.Not(checker.Contains), "Swarm is encrypted and needs to be unlocked") -- -- unlockKey = newUnlockKey -- } --} -- --// This differs from `TestSwarmRotateUnlockKey` because that one rotates a single node, which is the leader. --// This one keeps the leader up, and asserts that other manager nodes in the cluster also have their unlock --// key rotated. --func (s *DockerSwarmSuite) TestSwarmClusterRotateUnlockKey(c *check.C) { -- d1 := s.AddDaemon(c, true, true) // leader - don't restart this one, we don't want leader election delays -- d2 := s.AddDaemon(c, true, true) -- d3 := s.AddDaemon(c, true, true) -- -- outs, err := d1.Cmd("swarm", "update", "--autolock") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- -- c.Assert(outs, checker.Contains, "docker swarm unlock") -- -- var unlockKey string -- for _, line := range strings.Split(outs, "\n") { -- if strings.Contains(line, "SWMKEY") { -- unlockKey = strings.TrimSpace(line) -- break -- } -- } -- -- c.Assert(unlockKey, checker.Not(checker.Equals), "") -- -- outs, err = d1.Cmd("swarm", "unlock-key", "-q") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- c.Assert(outs, checker.Equals, unlockKey+"\n") -- -- // Rotate multiple times -- for i := 0; i != 3; i++ { -- outs, err = d1.Cmd("swarm", "unlock-key", "-q", "--rotate") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- // Strip \n -- newUnlockKey := outs[:len(outs)-1] -- c.Assert(newUnlockKey, checker.Not(checker.Equals), "") -- c.Assert(newUnlockKey, checker.Not(checker.Equals), unlockKey) -- -- d2.Restart(c) -- d3.Restart(c) -- -- for _, d := range []*daemon.Daemon{d2, d3} { -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateLocked) -- -- outs, _ := d.Cmd("node", "ls") -- c.Assert(outs, checker.Contains, "Swarm is encrypted and needs to be unlocked") -- -- cmd := d.Command("swarm", "unlock") -- cmd.Stdin = bytes.NewBufferString(unlockKey) -- result := icmd.RunCmd(cmd) -- -- if result.Error == nil { -- // On occasion, the daemon may not have finished -- // rotating the KEK before restarting. The test is -- // intentionally written to explore this behavior. -- // When this happens, unlocking with the old key will -- // succeed. If we wait for the rotation to happen and -- // restart again, the new key should be required this -- // time. -- -- time.Sleep(3 * time.Second) -- -- d.Restart(c) -- -- cmd = d.Command("swarm", "unlock") -- cmd.Stdin = bytes.NewBufferString(unlockKey) -- result = icmd.RunCmd(cmd) -- } -- result.Assert(c, icmd.Expected{ -- ExitCode: 1, -- Err: "invalid key", -- }) -- -- outs, _ = d.Cmd("node", "ls") -- c.Assert(outs, checker.Contains, "Swarm is encrypted and needs to be unlocked") -- -- cmd = d.Command("swarm", "unlock") -- cmd.Stdin = bytes.NewBufferString(newUnlockKey) -- icmd.RunCmd(cmd).Assert(c, icmd.Success) -- -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateActive) -- -- outs, err = d.Cmd("node", "ls") -- c.Assert(err, checker.IsNil, check.Commentf("%s", outs)) -- c.Assert(outs, checker.Not(checker.Contains), "Swarm is encrypted and needs to be unlocked") -- } -- -- unlockKey = newUnlockKey -- } --} -- --func (s *DockerSwarmSuite) TestSwarmAlternateLockUnlock(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- var unlockKey string -- for i := 0; i < 2; i++ { -- // set to lock -- outs, err := d.Cmd("swarm", "update", "--autolock") -- c.Assert(err, checker.IsNil, check.Commentf("out: %v", outs)) -- c.Assert(outs, checker.Contains, "docker swarm unlock") -- -- for _, line := range strings.Split(outs, "\n") { -- if strings.Contains(line, "SWMKEY") { -- unlockKey = strings.TrimSpace(line) -- break -- } -- } -- -- c.Assert(unlockKey, checker.Not(checker.Equals), "") -- checkSwarmUnlockedToLocked(c, d) -- -- cmd := d.Command("swarm", "unlock") -- cmd.Stdin = bytes.NewBufferString(unlockKey) -- icmd.RunCmd(cmd).Assert(c, icmd.Success) -- -- c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateActive) -- -- outs, err = d.Cmd("swarm", "update", "--autolock=false") -- c.Assert(err, checker.IsNil, check.Commentf("out: %v", outs)) -- -- checkSwarmLockedToUnlocked(c, d, unlockKey) -- } --} -- --func (s *DockerSwarmSuite) TestExtraHosts(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // Create a service -- name := "top" -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--host=example.com:1.2.3.4", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // Make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) -- -- // We need to get the container id. -- out, err = d.Cmd("ps", "-a", "-q", "--no-trunc") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- id := strings.TrimSpace(out) -- -- // Compare against expected output. -- expectedOutput := "1.2.3.4\texample.com" -- out, err = d.Cmd("exec", id, "cat", "/etc/hosts") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, expectedOutput, check.Commentf("Expected '%s', but got %q", expectedOutput, out)) --} -- --func (s *DockerSwarmSuite) TestSwarmManagerAddress(c *check.C) { -- d1 := s.AddDaemon(c, true, true) -- d2 := s.AddDaemon(c, true, false) -- d3 := s.AddDaemon(c, true, false) -- -- // Manager Addresses will always show Node 1's address -- expectedOutput := fmt.Sprintf("Manager Addresses:\n 127.0.0.1:%d\n", d1.SwarmPort) -- -- out, err := d1.Cmd("info") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, expectedOutput) -- -- out, err = d2.Cmd("info") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, expectedOutput) -- -- out, err = d3.Cmd("info") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, expectedOutput) --} -- --func (s *DockerSwarmSuite) TestSwarmNetworkIPAMOptions(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("network", "create", "-d", "overlay", "--ipam-opt", "foo=bar", "foo") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- out, err = d.Cmd("network", "inspect", "--format", "{{.IPAM.Options}}", "foo") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Contains, "foo:bar") -- c.Assert(strings.TrimSpace(out), checker.Contains, "com.docker.network.ipam.serial:true") -- -- out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--network=foo", "--name", "top", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) -- -- out, err = d.Cmd("network", "inspect", "--format", "{{.IPAM.Options}}", "foo") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Contains, "foo:bar") -- c.Assert(strings.TrimSpace(out), checker.Contains, "com.docker.network.ipam.serial:true") --} -- --// Test case for issue #27866, which did not allow NW name that is the prefix of a swarm NW ID. --// e.g. if the ingress ID starts with "n1", it was impossible to create a NW named "n1". --func (s *DockerSwarmSuite) TestSwarmNetworkCreateIssue27866(c *check.C) { -- d := s.AddDaemon(c, true, true) -- out, err := d.Cmd("network", "inspect", "-f", "{{.Id}}", "ingress") -- c.Assert(err, checker.IsNil, check.Commentf("out: %v", out)) -- ingressID := strings.TrimSpace(out) -- c.Assert(ingressID, checker.Not(checker.Equals), "") -- -- // create a network of which name is the prefix of the ID of an overlay network -- // (ingressID in this case) -- newNetName := ingressID[0:2] -- out, err = d.Cmd("network", "create", "--driver", "overlay", newNetName) -- // In #27866, it was failing because of "network with name %s already exists" -- c.Assert(err, checker.IsNil, check.Commentf("out: %v", out)) -- out, err = d.Cmd("network", "rm", newNetName) -- c.Assert(err, checker.IsNil, check.Commentf("out: %v", out)) --} -- --// Test case for https://github.com/docker/docker/pull/27938#issuecomment-265768303 --// This test creates two networks with the same name sequentially, with various drivers. --// Since the operations in this test are done sequentially, the 2nd call should fail with --// "network with name FOO already exists". --// Note that it is to ok have multiple networks with the same name if the operations are done --// in parallel. (#18864) --func (s *DockerSwarmSuite) TestSwarmNetworkCreateDup(c *check.C) { -- d := s.AddDaemon(c, true, true) -- drivers := []string{"bridge", "overlay"} -- for i, driver1 := range drivers { -- nwName := fmt.Sprintf("network-test-%d", i) -- for _, driver2 := range drivers { -- c.Logf("Creating a network named %q with %q, then %q", -- nwName, driver1, driver2) -- out, err := d.Cmd("network", "create", "--driver", driver1, nwName) -- c.Assert(err, checker.IsNil, check.Commentf("out: %v", out)) -- out, err = d.Cmd("network", "create", "--driver", driver2, nwName) -- c.Assert(out, checker.Contains, -- fmt.Sprintf("network with name %s already exists", nwName)) -- c.Assert(err, checker.NotNil) -- c.Logf("As expected, the attempt to network %q with %q failed: %s", -- nwName, driver2, out) -- out, err = d.Cmd("network", "rm", nwName) -- c.Assert(err, checker.IsNil, check.Commentf("out: %v", out)) -- } -- } --} -- --func (s *DockerSwarmSuite) TestSwarmPublishDuplicatePorts(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("service", "create", "--no-resolve-image", "--detach=true", "--publish", "5005:80", "--publish", "5006:80", "--publish", "80", "--publish", "80", "busybox", "top") -- c.Assert(err, check.IsNil, check.Commentf("%s", out)) -- id := strings.TrimSpace(out) -- -- // make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) -- -- // Total len = 4, with 2 dynamic ports and 2 non-dynamic ports -- // Dynamic ports are likely to be 30000 and 30001 but doesn't matter -- out, err = d.Cmd("service", "inspect", "--format", "{{.Endpoint.Ports}} len={{len .Endpoint.Ports}}", id) -- c.Assert(err, check.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, "len=4") -- c.Assert(out, checker.Contains, "{ tcp 80 5005 ingress}") -- c.Assert(out, checker.Contains, "{ tcp 80 5006 ingress}") --} -- --func (s *DockerSwarmSuite) TestSwarmJoinWithDrain(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("node", "ls") -- c.Assert(err, checker.IsNil) -- c.Assert(out, checker.Not(checker.Contains), "Drain") -- -- out, err = d.Cmd("swarm", "join-token", "-q", "manager") -- c.Assert(err, checker.IsNil) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- token := strings.TrimSpace(out) -- -- d1 := s.AddDaemon(c, false, false) -- -- out, err = d1.Cmd("swarm", "join", "--availability=drain", "--token", token, d.SwarmListenAddr()) -- c.Assert(err, checker.IsNil) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- out, err = d.Cmd("node", "ls") -- c.Assert(err, checker.IsNil) -- c.Assert(out, checker.Contains, "Drain") -- -- out, err = d1.Cmd("node", "ls") -- c.Assert(err, checker.IsNil) -- c.Assert(out, checker.Contains, "Drain") --} -- --func (s *DockerSwarmSuite) TestSwarmInitWithDrain(c *check.C) { -- d := s.AddDaemon(c, false, false) -- -- out, err := d.Cmd("swarm", "init", "--availability", "drain") -- c.Assert(err, checker.IsNil, check.Commentf("out: %v", out)) -- -- out, err = d.Cmd("node", "ls") -- c.Assert(err, checker.IsNil) -- c.Assert(out, checker.Contains, "Drain") --} -- --func (s *DockerSwarmSuite) TestSwarmReadonlyRootfs(c *check.C) { -- testRequires(c, DaemonIsLinux, UserNamespaceROMount) -- -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "top", "--read-only", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) -- -- out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.TaskTemplate.ContainerSpec.ReadOnly }}", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "true") -- -- containers := d.ActiveContainers(c) -- out, err = d.Cmd("inspect", "--type", "container", "--format", "{{.HostConfig.ReadonlyRootfs}}", containers[0]) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "true") --} -- --func (s *DockerSwarmSuite) TestNetworkInspectWithDuplicateNames(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- name := "foo" -- options := types.NetworkCreate{ -- CheckDuplicate: false, -- Driver: "bridge", -- } -- -- cli, err := d.NewClient() -- c.Assert(err, checker.IsNil) -- defer cli.Close() -- -- n1, err := cli.NetworkCreate(context.Background(), name, options) -- c.Assert(err, checker.IsNil) -- -- // Full ID always works -- out, err := d.Cmd("network", "inspect", "--format", "{{.ID}}", n1.ID) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, n1.ID) -- -- // Name works if it is unique -- out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", name) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, n1.ID) -- -- n2, err := cli.NetworkCreate(context.Background(), name, options) -- c.Assert(err, checker.IsNil) -- // Full ID always works -- out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", n1.ID) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, n1.ID) -- -- out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", n2.ID) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, n2.ID) -- -- // Name with duplicates -- out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", name) -- c.Assert(err, checker.NotNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, "2 matches found based on name") -- -- out, err = d.Cmd("network", "rm", n2.ID) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // Dupliates with name but with different driver -- options.Driver = "overlay" -- -- n2, err = cli.NetworkCreate(context.Background(), name, options) -- c.Assert(err, checker.IsNil) -- -- // Full ID always works -- out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", n1.ID) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, n1.ID) -- -- out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", n2.ID) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, n2.ID) -- -- // Name with duplicates -- out, err = d.Cmd("network", "inspect", "--format", "{{.ID}}", name) -- c.Assert(err, checker.NotNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, "2 matches found based on name") --} -- --func (s *DockerSwarmSuite) TestSwarmStopSignal(c *check.C) { -- testRequires(c, DaemonIsLinux, UserNamespaceROMount) -- -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "top", "--stop-signal=SIGHUP", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) -- -- out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.TaskTemplate.ContainerSpec.StopSignal }}", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "SIGHUP") -- -- containers := d.ActiveContainers(c) -- out, err = d.Cmd("inspect", "--type", "container", "--format", "{{.Config.StopSignal}}", containers[0]) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "SIGHUP") -- -- out, err = d.Cmd("service", "update", "--detach", "--stop-signal=SIGUSR1", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.TaskTemplate.ContainerSpec.StopSignal }}", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Equals, "SIGUSR1") --} -- --func (s *DockerSwarmSuite) TestSwarmServiceLsFilterMode(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "top1", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- out, err = d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", "top2", "--mode=global", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- // make sure task has been deployed. -- waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 2) -- -- out, err = d.Cmd("service", "ls") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, "top1") -- c.Assert(out, checker.Contains, "top2") -- c.Assert(out, checker.Not(checker.Contains), "localnet") -- -- out, err = d.Cmd("service", "ls", "--filter", "mode=global") -- c.Assert(out, checker.Not(checker.Contains), "top1") -- c.Assert(out, checker.Contains, "top2") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- out, err = d.Cmd("service", "ls", "--filter", "mode=replicated") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- c.Assert(out, checker.Contains, "top1") -- c.Assert(out, checker.Not(checker.Contains), "top2") --} -- --func (s *DockerSwarmSuite) TestSwarmInitUnspecifiedDataPathAddr(c *check.C) { -- d := s.AddDaemon(c, false, false) -- -- out, err := d.Cmd("swarm", "init", "--data-path-addr", "0.0.0.0") -- c.Assert(err, checker.NotNil) -- c.Assert(out, checker.Contains, "data path address must be a non-zero IP") -- -- out, err = d.Cmd("swarm", "init", "--data-path-addr", "0.0.0.0:2000") -- c.Assert(err, checker.NotNil) -- c.Assert(out, checker.Contains, "data path address must be a non-zero IP") --} -- --func (s *DockerSwarmSuite) TestSwarmJoinLeave(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- out, err := d.Cmd("swarm", "join-token", "-q", "worker") -- c.Assert(err, checker.IsNil) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- token := strings.TrimSpace(out) -- -- // Verify that back to back join/leave does not cause panics -- d1 := s.AddDaemon(c, false, false) -- for i := 0; i < 10; i++ { -- out, err = d1.Cmd("swarm", "join", "--token", token, d.SwarmListenAddr()) -- c.Assert(err, checker.IsNil) -- c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") -- -- _, err = d1.Cmd("swarm", "leave") -- c.Assert(err, checker.IsNil) -- } --} -- --const defaultRetryCount = 10 -- --func waitForEvent(c *check.C, d *daemon.Daemon, since string, filter string, event string, retry int) string { -- if retry < 1 { -- c.Fatalf("retry count %d is invalid. It should be no less than 1", retry) -- return "" -- } -- var out string -- for i := 0; i < retry; i++ { -- until := daemonUnixTime(c) -- var err error -- if len(filter) > 0 { -- out, err = d.Cmd("events", "--since", since, "--until", until, filter) -- } else { -- out, err = d.Cmd("events", "--since", since, "--until", until) -- } -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- if strings.Contains(out, event) { -- return strings.TrimSpace(out) -- } -- // no need to sleep after last retry -- if i < retry-1 { -- time.Sleep(200 * time.Millisecond) -- } -- } -- c.Fatalf("docker events output '%s' doesn't contain event '%s'", out, event) -- return "" --} -- --func (s *DockerSwarmSuite) TestSwarmClusterEventsSource(c *check.C) { -- d1 := s.AddDaemon(c, true, true) -- d2 := s.AddDaemon(c, true, true) -- d3 := s.AddDaemon(c, true, false) -- -- // create a network -- out, err := d1.Cmd("network", "create", "--attachable", "-d", "overlay", "foo") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- networkID := strings.TrimSpace(out) -- c.Assert(networkID, checker.Not(checker.Equals), "") -- -- // d1, d2 are managers that can get swarm events -- waitForEvent(c, d1, "0", "-f scope=swarm", "network create "+networkID, defaultRetryCount) -- waitForEvent(c, d2, "0", "-f scope=swarm", "network create "+networkID, defaultRetryCount) -- -- // d3 is a worker, not able to get cluster events -- out = waitForEvent(c, d3, "0", "-f scope=swarm", "", 1) -- c.Assert(out, checker.Not(checker.Contains), "network create ") --} -- --func (s *DockerSwarmSuite) TestSwarmClusterEventsScope(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // create a service -- out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", "test", "--detach=false", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- serviceID := strings.Split(out, "\n")[0] -- -- // scope swarm filters cluster events -- out = waitForEvent(c, d, "0", "-f scope=swarm", "service create "+serviceID, defaultRetryCount) -- c.Assert(out, checker.Not(checker.Contains), "container create ") -- -- // all events are returned if scope is not specified -- waitForEvent(c, d, "0", "", "service create "+serviceID, 1) -- waitForEvent(c, d, "0", "", "container create ", defaultRetryCount) -- -- // scope local only shows non-cluster events -- out = waitForEvent(c, d, "0", "-f scope=local", "container create ", 1) -- c.Assert(out, checker.Not(checker.Contains), "service create ") --} -- --func (s *DockerSwarmSuite) TestSwarmClusterEventsType(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // create a service -- out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", "test", "--detach=false", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- serviceID := strings.Split(out, "\n")[0] -- -- // create a network -- out, err = d.Cmd("network", "create", "--attachable", "-d", "overlay", "foo") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- networkID := strings.TrimSpace(out) -- c.Assert(networkID, checker.Not(checker.Equals), "") -- -- // filter by service -- out = waitForEvent(c, d, "0", "-f type=service", "service create "+serviceID, defaultRetryCount) -- c.Assert(out, checker.Not(checker.Contains), "network create") -- -- // filter by network -- out = waitForEvent(c, d, "0", "-f type=network", "network create "+networkID, defaultRetryCount) -- c.Assert(out, checker.Not(checker.Contains), "service create") --} -- --func (s *DockerSwarmSuite) TestSwarmClusterEventsService(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // create a service -- out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", "test", "--detach=false", "busybox", "top") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- serviceID := strings.Split(out, "\n")[0] -- -- // validate service create event -- waitForEvent(c, d, "0", "-f scope=swarm", "service create "+serviceID, defaultRetryCount) -- -- t1 := daemonUnixTime(c) -- out, err = d.Cmd("service", "update", "--force", "--detach=false", "test") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // wait for service update start -- out = waitForEvent(c, d, t1, "-f scope=swarm", "service update "+serviceID, defaultRetryCount) -- c.Assert(out, checker.Contains, "updatestate.new=updating") -- -- // allow service update complete. This is a service with 1 instance -- time.Sleep(400 * time.Millisecond) -- out = waitForEvent(c, d, t1, "-f scope=swarm", "service update "+serviceID, defaultRetryCount) -- c.Assert(out, checker.Contains, "updatestate.new=completed, updatestate.old=updating") -- -- // scale service -- t2 := daemonUnixTime(c) -- out, err = d.Cmd("service", "scale", "test=3") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- out = waitForEvent(c, d, t2, "-f scope=swarm", "service update "+serviceID, defaultRetryCount) -- c.Assert(out, checker.Contains, "replicas.new=3, replicas.old=1") -- -- // remove service -- t3 := daemonUnixTime(c) -- out, err = d.Cmd("service", "rm", "test") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- waitForEvent(c, d, t3, "-f scope=swarm", "service remove "+serviceID, defaultRetryCount) --} -- --func (s *DockerSwarmSuite) TestSwarmClusterEventsNode(c *check.C) { -- d1 := s.AddDaemon(c, true, true) -- s.AddDaemon(c, true, true) -- d3 := s.AddDaemon(c, true, true) -- -- d3ID := d3.NodeID() -- waitForEvent(c, d1, "0", "-f scope=swarm", "node create "+d3ID, defaultRetryCount) -- -- t1 := daemonUnixTime(c) -- out, err := d1.Cmd("node", "update", "--availability=pause", d3ID) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // filter by type -- out = waitForEvent(c, d1, t1, "-f type=node", "node update "+d3ID, defaultRetryCount) -- c.Assert(out, checker.Contains, "availability.new=pause, availability.old=active") -- -- t2 := daemonUnixTime(c) -- out, err = d1.Cmd("node", "demote", d3ID) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- waitForEvent(c, d1, t2, "-f type=node", "node update "+d3ID, defaultRetryCount) -- -- t3 := daemonUnixTime(c) -- out, err = d1.Cmd("node", "rm", "-f", d3ID) -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // filter by scope -- waitForEvent(c, d1, t3, "-f scope=swarm", "node remove "+d3ID, defaultRetryCount) --} -- --func (s *DockerSwarmSuite) TestSwarmClusterEventsNetwork(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- // create a network -- out, err := d.Cmd("network", "create", "--attachable", "-d", "overlay", "foo") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- networkID := strings.TrimSpace(out) -- -- waitForEvent(c, d, "0", "-f scope=swarm", "network create "+networkID, defaultRetryCount) -- -- // remove network -- t1 := daemonUnixTime(c) -- out, err = d.Cmd("network", "rm", "foo") -- c.Assert(err, checker.IsNil, check.Commentf("%s", out)) -- -- // filtered by network -- waitForEvent(c, d, t1, "-f type=network", "network remove "+networkID, defaultRetryCount) --} -- --func (s *DockerSwarmSuite) TestSwarmClusterEventsSecret(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- testName := "test_secret" -- id := d.CreateSecret(c, swarm.SecretSpec{ -- Annotations: swarm.Annotations{ -- Name: testName, -- }, -- Data: []byte("TESTINGDATA"), -- }) -- c.Assert(id, checker.Not(checker.Equals), "", check.Commentf("secrets: %s", id)) -- -- waitForEvent(c, d, "0", "-f scope=swarm", "secret create "+id, defaultRetryCount) -- -- t1 := daemonUnixTime(c) -- d.DeleteSecret(c, id) -- // filtered by secret -- waitForEvent(c, d, t1, "-f type=secret", "secret remove "+id, defaultRetryCount) --} -- --func (s *DockerSwarmSuite) TestSwarmClusterEventsConfig(c *check.C) { -- d := s.AddDaemon(c, true, true) -- -- testName := "test_config" -- id := d.CreateConfig(c, swarm.ConfigSpec{ -- Annotations: swarm.Annotations{ -- Name: testName, -- }, -- Data: []byte("TESTINGDATA"), -- }) -- c.Assert(id, checker.Not(checker.Equals), "", check.Commentf("configs: %s", id)) -- -- waitForEvent(c, d, "0", "-f scope=swarm", "config create "+id, defaultRetryCount) -- -- t1 := daemonUnixTime(c) -- d.DeleteConfig(c, id) -- // filtered by config -- waitForEvent(c, d, t1, "-f type=config", "config remove "+id, defaultRetryCount) --} --- -2.17.1 - diff --git a/patch/0067-pause-fix-build-missing-dep-packages.patch b/patch/0067-pause-fix-build-missing-dep-packages.patch deleted file mode 100644 index f7aa1ab..0000000 --- a/patch/0067-pause-fix-build-missing-dep-packages.patch +++ /dev/null @@ -1,5759 +0,0 @@ -From 962e669ab1b1d3545faca5b668ca9d1be0d3b786 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Mon, 21 Jan 2019 21:25:33 +0800 -Subject: [PATCH 067/111] pause: fix build missing dep packages - -reason: update vendor for libcontainer/cgroup dependency. - -checkout from runc-1.0.0: -eff62015 runc: support specify umask -- coreos/go-systemd/util -- opencontainers/runc/libcontainer/cgroups/fs -- opencontainers/runc/libcontainer/cgroups/systemd -- opencontainers/runc/libcontainer/utils - -files modified support FilesLimit: -- opencontainers/runc/libcontainer/cgroups/stats.go -- opencontainers/runc/libcontainer/configs/cgroup_linux.go - -Change-Id: I794f0bf9be87c6068788f866555c346ca2372c02 -Signed-off-by: jingrui ---- - .../github.com/coreos/go-systemd/Checklist | 2 + - .../github.com/coreos/go-systemd/util/util.go | 33 + - .../runc/libcontainer/Checklist | 4 + - .../runc/libcontainer/cgroups/fs/apply_raw.go | 361 ++++++++++ - .../libcontainer/cgroups/fs/apply_raw_test.go | 272 ++++++++ - .../runc/libcontainer/cgroups/fs/blkio.go | 237 +++++++ - .../libcontainer/cgroups/fs/blkio_test.go | 636 ++++++++++++++++++ - .../runc/libcontainer/cgroups/fs/cpu.go | 125 ++++ - .../runc/libcontainer/cgroups/fs/cpu_test.go | 209 ++++++ - .../runc/libcontainer/cgroups/fs/cpuacct.go | 121 ++++ - .../runc/libcontainer/cgroups/fs/cpuset.go | 183 +++++ - .../libcontainer/cgroups/fs/cpuset_test.go | 65 ++ - .../runc/libcontainer/cgroups/fs/devices.go | 80 +++ - .../libcontainer/cgroups/fs/devices_test.go | 98 +++ - .../runc/libcontainer/cgroups/fs/files.go | 72 ++ - .../runc/libcontainer/cgroups/fs/freezer.go | 61 ++ - .../libcontainer/cgroups/fs/freezer_test.go | 47 ++ - .../libcontainer/cgroups/fs/fs_unsupported.go | 3 + - .../runc/libcontainer/cgroups/fs/hugetlb.go | 71 ++ - .../libcontainer/cgroups/fs/hugetlb_test.go | 154 +++++ - .../runc/libcontainer/cgroups/fs/memory.go | 301 +++++++++ - .../libcontainer/cgroups/fs/memory_test.go | 453 +++++++++++++ - .../runc/libcontainer/cgroups/fs/name.go | 40 ++ - .../runc/libcontainer/cgroups/fs/net_cls.go | 43 ++ - .../libcontainer/cgroups/fs/net_cls_test.go | 39 ++ - .../runc/libcontainer/cgroups/fs/net_prio.go | 41 ++ - .../libcontainer/cgroups/fs/net_prio_test.go | 38 ++ - .../libcontainer/cgroups/fs/perf_event.go | 35 + - .../runc/libcontainer/cgroups/fs/pids.go | 73 ++ - .../runc/libcontainer/cgroups/fs/pids_test.go | 111 +++ - .../cgroups/fs/stats_util_test.go | 117 ++++ - .../runc/libcontainer/cgroups/fs/util_test.go | 67 ++ - .../runc/libcontainer/cgroups/fs/utils.go | 78 +++ - .../libcontainer/cgroups/fs/utils_test.go | 97 +++ - .../libcontainer/cgroups/rootless/rootless.go | 128 ++++ - .../runc/libcontainer/cgroups/stats.go | 8 + - .../cgroups/systemd/apply_nosystemd.go | 55 ++ - .../cgroups/systemd/apply_systemd.go | 556 +++++++++++++++ - .../runc/libcontainer/configs/cgroup_linux.go | 3 + - .../runc/libcontainer/utils/cmsg.go | 95 +++ - .../runc/libcontainer/utils/utils.go | 126 ++++ - .../runc/libcontainer/utils/utils_unix.go | 43 ++ - 42 files changed, 5381 insertions(+) - create mode 100644 components/engine/vendor/github.com/coreos/go-systemd/Checklist - create mode 100644 components/engine/vendor/github.com/coreos/go-systemd/util/util.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/Checklist - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/files.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs_unsupported.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/perf_event.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/stats_util_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/util_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils_test.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/rootless/rootless.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_nosystemd.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go - create mode 100644 components/engine/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go - -diff --git a/components/engine/vendor/github.com/coreos/go-systemd/Checklist b/components/engine/vendor/github.com/coreos/go-systemd/Checklist -new file mode 100644 -index 0000000000..c231fc1636 ---- /dev/null -+++ b/components/engine/vendor/github.com/coreos/go-systemd/Checklist -@@ -0,0 +1,2 @@ -+Add these packages from go-systemd v4 for moving Pause handling from runc to dockerd -+- github.com/coreos/go-systemd/util -\ No newline at end of file -diff --git a/components/engine/vendor/github.com/coreos/go-systemd/util/util.go b/components/engine/vendor/github.com/coreos/go-systemd/util/util.go -new file mode 100644 -index 0000000000..33832a1ed4 ---- /dev/null -+++ b/components/engine/vendor/github.com/coreos/go-systemd/util/util.go -@@ -0,0 +1,33 @@ -+// Copyright 2015 CoreOS, Inc. -+// -+// Licensed under the Apache License, Version 2.0 (the "License"); -+// you may not use this file except in compliance with the License. -+// You may obtain a copy of the License at -+// -+// http://www.apache.org/licenses/LICENSE-2.0 -+// -+// Unless required by applicable law or agreed to in writing, software -+// distributed under the License is distributed on an "AS IS" BASIS, -+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+// See the License for the specific language governing permissions and -+// limitations under the License. -+ -+// Package util contains utility functions related to systemd that applications -+// can use to check things like whether systemd is running. -+package util -+ -+import ( -+ "os" -+) -+ -+// IsRunningSystemd checks whether the host was booted with systemd as its init -+// system. This functions similar to systemd's `sd_booted(3)`: internally, it -+// checks whether /run/systemd/system/ exists and is a directory. -+// http://www.freedesktop.org/software/systemd/man/sd_booted.html -+func IsRunningSystemd() bool { -+ fi, err := os.Lstat("/run/systemd/system") -+ if err != nil { -+ return false -+ } -+ return fi.IsDir() -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/Checklist b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/Checklist -new file mode 100644 -index 0000000000..d0900fc618 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/Checklist -@@ -0,0 +1,4 @@ -+Add these packages for moving Pause handling from runc to dockerd -+- github.com/opencontainers/runc/libcontainer/cgroups/fs -+- github.com/opencontainers/runc/libcontainer/cgroups/systemd -+- github.com/opencontainers/runc/libcontainer/utils -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go -new file mode 100644 -index 0000000000..1bf59a47be ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw.go -@@ -0,0 +1,361 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "errors" -+ "fmt" -+ "io" -+ "io/ioutil" -+ "os" -+ "path/filepath" -+ "sync" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+ libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils" -+) -+ -+var ( -+ subsystems = subsystemSet{ -+ &CpusetGroup{}, -+ &DevicesGroup{}, -+ &MemoryGroup{}, -+ &CpuGroup{}, -+ &CpuacctGroup{}, -+ &PidsGroup{}, -+ &FilesGroup{}, -+ &BlkioGroup{}, -+ &HugetlbGroup{}, -+ &NetClsGroup{}, -+ &NetPrioGroup{}, -+ &PerfEventGroup{}, -+ &FreezerGroup{}, -+ &NameGroup{GroupName: "name=systemd", Join: true}, -+ } -+ HugePageSizes, _ = cgroups.GetHugePageSize() -+) -+ -+var errSubsystemDoesNotExist = errors.New("cgroup: subsystem does not exist") -+ -+type subsystemSet []subsystem -+ -+func (s subsystemSet) Get(name string) (subsystem, error) { -+ for _, ss := range s { -+ if ss.Name() == name { -+ return ss, nil -+ } -+ } -+ return nil, errSubsystemDoesNotExist -+} -+ -+type subsystem interface { -+ // Name returns the name of the subsystem. -+ Name() string -+ // Returns the stats, as 'stats', corresponding to the cgroup under 'path'. -+ GetStats(path string, stats *cgroups.Stats) error -+ // Removes the cgroup represented by 'cgroupData'. -+ Remove(*cgroupData) error -+ // Creates and joins the cgroup represented by 'cgroupData'. -+ Apply(*cgroupData) error -+ // Set the cgroup represented by cgroup. -+ Set(path string, cgroup *configs.Cgroup) error -+} -+ -+type Manager struct { -+ mu sync.Mutex -+ Cgroups *configs.Cgroup -+ Paths map[string]string -+} -+ -+// The absolute path to the root of the cgroup hierarchies. -+var cgroupRootLock sync.Mutex -+var cgroupRoot string -+ -+// Gets the cgroupRoot. -+func getCgroupRoot() (string, error) { -+ cgroupRootLock.Lock() -+ defer cgroupRootLock.Unlock() -+ -+ if cgroupRoot != "" { -+ return cgroupRoot, nil -+ } -+ -+ root, err := cgroups.FindCgroupMountpointDir() -+ if err != nil { -+ return "", err -+ } -+ -+ if _, err := os.Stat(root); err != nil { -+ return "", err -+ } -+ -+ cgroupRoot = root -+ return cgroupRoot, nil -+} -+ -+type cgroupData struct { -+ root string -+ innerPath string -+ config *configs.Cgroup -+ pid int -+} -+ -+func (m *Manager) Apply(pid int) (err error) { -+ if m.Cgroups == nil { -+ return nil -+ } -+ m.mu.Lock() -+ defer m.mu.Unlock() -+ -+ var c = m.Cgroups -+ -+ d, err := getCgroupData(m.Cgroups, pid) -+ if err != nil { -+ return err -+ } -+ -+ m.Paths = make(map[string]string) -+ if c.Paths != nil { -+ for name, path := range c.Paths { -+ _, err := d.path(name) -+ if err != nil { -+ if cgroups.IsNotFound(err) { -+ continue -+ } -+ return err -+ } -+ m.Paths[name] = path -+ } -+ return cgroups.EnterPid(m.Paths, pid) -+ } -+ -+ for _, sys := range subsystems { -+ // TODO: Apply should, ideally, be reentrant or be broken up into a separate -+ // create and join phase so that the cgroup hierarchy for a container can be -+ // created then join consists of writing the process pids to cgroup.procs -+ p, err := d.path(sys.Name()) -+ if err != nil { -+ // The non-presence of the devices subsystem is -+ // considered fatal for security reasons. -+ if cgroups.IsNotFound(err) && sys.Name() != "devices" { -+ continue -+ } -+ return err -+ } -+ m.Paths[sys.Name()] = p -+ -+ if err := sys.Apply(d); err != nil { -+ return err -+ } -+ } -+ return nil -+} -+ -+func (m *Manager) Destroy() error { -+ if m.Cgroups == nil || m.Cgroups.Paths != nil { -+ return nil -+ } -+ m.mu.Lock() -+ defer m.mu.Unlock() -+ if err := cgroups.RemovePaths(m.Paths); err != nil { -+ return err -+ } -+ m.Paths = make(map[string]string) -+ return nil -+} -+ -+func (m *Manager) GetPaths() map[string]string { -+ m.mu.Lock() -+ paths := m.Paths -+ m.mu.Unlock() -+ return paths -+} -+ -+func (m *Manager) GetStats() (*cgroups.Stats, error) { -+ m.mu.Lock() -+ defer m.mu.Unlock() -+ stats := cgroups.NewStats() -+ for name, path := range m.Paths { -+ sys, err := subsystems.Get(name) -+ if err == errSubsystemDoesNotExist || !cgroups.PathExists(path) { -+ continue -+ } -+ if err := sys.GetStats(path, stats); err != nil { -+ return nil, err -+ } -+ } -+ return stats, nil -+} -+ -+func (m *Manager) Set(container *configs.Config) error { -+ // If Paths are set, then we are just joining cgroups paths -+ // and there is no need to set any values. -+ if m.Cgroups.Paths != nil { -+ return nil -+ } -+ -+ paths := m.GetPaths() -+ for _, sys := range subsystems { -+ path := paths[sys.Name()] -+ if err := sys.Set(path, container.Cgroups); err != nil { -+ return err -+ } -+ } -+ -+ if m.Paths["cpu"] != "" { -+ if err := CheckCpushares(m.Paths["cpu"], container.Cgroups.Resources.CpuShares); err != nil { -+ return err -+ } -+ } -+ return nil -+} -+ -+// Freeze toggles the container's freezer cgroup depending on the state -+// provided -+func (m *Manager) Freeze(state configs.FreezerState) error { -+ paths := m.GetPaths() -+ dir := paths["freezer"] -+ prevState := m.Cgroups.Resources.Freezer -+ m.Cgroups.Resources.Freezer = state -+ freezer, err := subsystems.Get("freezer") -+ if err != nil { -+ return err -+ } -+ err = freezer.Set(dir, m.Cgroups) -+ if err != nil { -+ m.Cgroups.Resources.Freezer = prevState -+ return err -+ } -+ return nil -+} -+ -+func (m *Manager) GetPids() ([]int, error) { -+ paths := m.GetPaths() -+ return cgroups.GetPids(paths["devices"]) -+} -+ -+func (m *Manager) GetAllPids() ([]int, error) { -+ paths := m.GetPaths() -+ return cgroups.GetAllPids(paths["devices"]) -+} -+ -+func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) { -+ root, err := getCgroupRoot() -+ if err != nil { -+ return nil, err -+ } -+ -+ if (c.Name != "" || c.Parent != "") && c.Path != "" { -+ return nil, fmt.Errorf("cgroup: either Path or Name and Parent should be used") -+ } -+ -+ // XXX: Do not remove this code. Path safety is important! -- cyphar -+ cgPath := libcontainerUtils.CleanPath(c.Path) -+ cgParent := libcontainerUtils.CleanPath(c.Parent) -+ cgName := libcontainerUtils.CleanPath(c.Name) -+ -+ innerPath := cgPath -+ if innerPath == "" { -+ innerPath = filepath.Join(cgParent, cgName) -+ } -+ -+ return &cgroupData{ -+ root: root, -+ innerPath: innerPath, -+ config: c, -+ pid: pid, -+ }, nil -+} -+ -+func (raw *cgroupData) path(subsystem string) (string, error) { -+ mnt, err := cgroups.FindCgroupMountpoint(subsystem) -+ // If we didn't mount the subsystem, there is no point we make the path. -+ if err != nil { -+ return "", err -+ } -+ -+ // If the cgroup name/path is absolute do not look relative to the cgroup of the init process. -+ if filepath.IsAbs(raw.innerPath) { -+ // Sometimes subsystems can be mounted together as 'cpu,cpuacct'. -+ return filepath.Join(raw.root, filepath.Base(mnt), raw.innerPath), nil -+ } -+ -+ // Use GetOwnCgroupPath instead of GetInitCgroupPath, because the creating -+ // process could in container and shared pid namespace with host, and -+ // /proc/1/cgroup could point to whole other world of cgroups. -+ parentPath, err := cgroups.GetOwnCgroupPath(subsystem) -+ if err != nil { -+ return "", err -+ } -+ -+ return filepath.Join(parentPath, raw.innerPath), nil -+} -+ -+func (raw *cgroupData) join(subsystem string) (string, error) { -+ path, err := raw.path(subsystem) -+ if err != nil { -+ return "", err -+ } -+ if err := os.MkdirAll(path, 0755); err != nil { -+ return "", err -+ } -+ if err := cgroups.WriteCgroupProc(path, raw.pid); err != nil { -+ return "", err -+ } -+ return path, nil -+} -+ -+func writeFile(dir, file, data string) error { -+ // Normally dir should not be empty, one case is that cgroup subsystem -+ // is not mounted, we will get empty dir, and we want it fail here. -+ if dir == "" { -+ return fmt.Errorf("no such directory for %s", file) -+ } -+ if err := ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700); err != nil { -+ return fmt.Errorf("failed to write %v to %v: %v", data, file, err) -+ } -+ return nil -+} -+ -+func readFile(dir, file string) (string, error) { -+ data, err := ioutil.ReadFile(filepath.Join(dir, file)) -+ return string(data), err -+} -+ -+func removePath(p string, err error) error { -+ if err != nil { -+ return err -+ } -+ if p != "" { -+ return os.RemoveAll(p) -+ } -+ return nil -+} -+ -+func CheckCpushares(path string, c uint64) error { -+ var cpuShares uint64 -+ -+ if c == 0 { -+ return nil -+ } -+ -+ fd, err := os.Open(filepath.Join(path, "cpu.shares")) -+ if err != nil { -+ return err -+ } -+ defer fd.Close() -+ -+ _, err = fmt.Fscanf(fd, "%d", &cpuShares) -+ if err != nil && err != io.EOF { -+ return err -+ } -+ -+ if c > cpuShares { -+ return fmt.Errorf("The maximum allowed cpu-shares is %d", cpuShares) -+ } else if c < cpuShares { -+ return fmt.Errorf("The minimum allowed cpu-shares is %d", cpuShares) -+ } -+ -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw_test.go -new file mode 100644 -index 0000000000..ba4e9e543c ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/apply_raw_test.go -@@ -0,0 +1,272 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "path/filepath" -+ "strings" -+ "testing" -+ -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+func TestInvalidCgroupPath(t *testing.T) { -+ root, err := getCgroupRoot() -+ if err != nil { -+ t.Errorf("couldn't get cgroup root: %v", err) -+ } -+ -+ config := &configs.Cgroup{ -+ Path: "../../../../../../../../../../some/path", -+ } -+ -+ data, err := getCgroupData(config, 0) -+ if err != nil { -+ t.Errorf("couldn't get cgroup data: %v", err) -+ } -+ -+ // Make sure the final innerPath doesn't go outside the cgroup mountpoint. -+ if strings.HasPrefix(data.innerPath, "..") { -+ t.Errorf("SECURITY: cgroup innerPath is outside cgroup mountpoint!") -+ } -+ -+ // Double-check, using an actual cgroup. -+ deviceRoot := filepath.Join(root, "devices") -+ devicePath, err := data.path("devices") -+ if err != nil { -+ t.Errorf("couldn't get cgroup path: %v", err) -+ } -+ if !strings.HasPrefix(devicePath, deviceRoot) { -+ t.Errorf("SECURITY: cgroup path() is outside cgroup mountpoint!") -+ } -+} -+ -+func TestInvalidAbsoluteCgroupPath(t *testing.T) { -+ root, err := getCgroupRoot() -+ if err != nil { -+ t.Errorf("couldn't get cgroup root: %v", err) -+ } -+ -+ config := &configs.Cgroup{ -+ Path: "/../../../../../../../../../../some/path", -+ } -+ -+ data, err := getCgroupData(config, 0) -+ if err != nil { -+ t.Errorf("couldn't get cgroup data: %v", err) -+ } -+ -+ // Make sure the final innerPath doesn't go outside the cgroup mountpoint. -+ if strings.HasPrefix(data.innerPath, "..") { -+ t.Errorf("SECURITY: cgroup innerPath is outside cgroup mountpoint!") -+ } -+ -+ // Double-check, using an actual cgroup. -+ deviceRoot := filepath.Join(root, "devices") -+ devicePath, err := data.path("devices") -+ if err != nil { -+ t.Errorf("couldn't get cgroup path: %v", err) -+ } -+ if !strings.HasPrefix(devicePath, deviceRoot) { -+ t.Errorf("SECURITY: cgroup path() is outside cgroup mountpoint!") -+ } -+} -+ -+// XXX: Remove me after we get rid of configs.Cgroup.Name and configs.Cgroup.Parent. -+func TestInvalidCgroupParent(t *testing.T) { -+ root, err := getCgroupRoot() -+ if err != nil { -+ t.Errorf("couldn't get cgroup root: %v", err) -+ } -+ -+ config := &configs.Cgroup{ -+ Parent: "../../../../../../../../../../some/path", -+ Name: "name", -+ } -+ -+ data, err := getCgroupData(config, 0) -+ if err != nil { -+ t.Errorf("couldn't get cgroup data: %v", err) -+ } -+ -+ // Make sure the final innerPath doesn't go outside the cgroup mountpoint. -+ if strings.HasPrefix(data.innerPath, "..") { -+ t.Errorf("SECURITY: cgroup innerPath is outside cgroup mountpoint!") -+ } -+ -+ // Double-check, using an actual cgroup. -+ deviceRoot := filepath.Join(root, "devices") -+ devicePath, err := data.path("devices") -+ if err != nil { -+ t.Errorf("couldn't get cgroup path: %v", err) -+ } -+ if !strings.HasPrefix(devicePath, deviceRoot) { -+ t.Errorf("SECURITY: cgroup path() is outside cgroup mountpoint!") -+ } -+} -+ -+// XXX: Remove me after we get rid of configs.Cgroup.Name and configs.Cgroup.Parent. -+func TestInvalidAbsoluteCgroupParent(t *testing.T) { -+ root, err := getCgroupRoot() -+ if err != nil { -+ t.Errorf("couldn't get cgroup root: %v", err) -+ } -+ -+ config := &configs.Cgroup{ -+ Parent: "/../../../../../../../../../../some/path", -+ Name: "name", -+ } -+ -+ data, err := getCgroupData(config, 0) -+ if err != nil { -+ t.Errorf("couldn't get cgroup data: %v", err) -+ } -+ -+ // Make sure the final innerPath doesn't go outside the cgroup mountpoint. -+ if strings.HasPrefix(data.innerPath, "..") { -+ t.Errorf("SECURITY: cgroup innerPath is outside cgroup mountpoint!") -+ } -+ -+ // Double-check, using an actual cgroup. -+ deviceRoot := filepath.Join(root, "devices") -+ devicePath, err := data.path("devices") -+ if err != nil { -+ t.Errorf("couldn't get cgroup path: %v", err) -+ } -+ if !strings.HasPrefix(devicePath, deviceRoot) { -+ t.Errorf("SECURITY: cgroup path() is outside cgroup mountpoint!") -+ } -+} -+ -+// XXX: Remove me after we get rid of configs.Cgroup.Name and configs.Cgroup.Parent. -+func TestInvalidCgroupName(t *testing.T) { -+ root, err := getCgroupRoot() -+ if err != nil { -+ t.Errorf("couldn't get cgroup root: %v", err) -+ } -+ -+ config := &configs.Cgroup{ -+ Parent: "parent", -+ Name: "../../../../../../../../../../some/path", -+ } -+ -+ data, err := getCgroupData(config, 0) -+ if err != nil { -+ t.Errorf("couldn't get cgroup data: %v", err) -+ } -+ -+ // Make sure the final innerPath doesn't go outside the cgroup mountpoint. -+ if strings.HasPrefix(data.innerPath, "..") { -+ t.Errorf("SECURITY: cgroup innerPath is outside cgroup mountpoint!") -+ } -+ -+ // Double-check, using an actual cgroup. -+ deviceRoot := filepath.Join(root, "devices") -+ devicePath, err := data.path("devices") -+ if err != nil { -+ t.Errorf("couldn't get cgroup path: %v", err) -+ } -+ if !strings.HasPrefix(devicePath, deviceRoot) { -+ t.Errorf("SECURITY: cgroup path() is outside cgroup mountpoint!") -+ } -+ -+} -+ -+// XXX: Remove me after we get rid of configs.Cgroup.Name and configs.Cgroup.Parent. -+func TestInvalidAbsoluteCgroupName(t *testing.T) { -+ root, err := getCgroupRoot() -+ if err != nil { -+ t.Errorf("couldn't get cgroup root: %v", err) -+ } -+ -+ config := &configs.Cgroup{ -+ Parent: "parent", -+ Name: "/../../../../../../../../../../some/path", -+ } -+ -+ data, err := getCgroupData(config, 0) -+ if err != nil { -+ t.Errorf("couldn't get cgroup data: %v", err) -+ } -+ -+ // Make sure the final innerPath doesn't go outside the cgroup mountpoint. -+ if strings.HasPrefix(data.innerPath, "..") { -+ t.Errorf("SECURITY: cgroup innerPath is outside cgroup mountpoint!") -+ } -+ -+ // Double-check, using an actual cgroup. -+ deviceRoot := filepath.Join(root, "devices") -+ devicePath, err := data.path("devices") -+ if err != nil { -+ t.Errorf("couldn't get cgroup path: %v", err) -+ } -+ if !strings.HasPrefix(devicePath, deviceRoot) { -+ t.Errorf("SECURITY: cgroup path() is outside cgroup mountpoint!") -+ } -+} -+ -+// XXX: Remove me after we get rid of configs.Cgroup.Name and configs.Cgroup.Parent. -+func TestInvalidCgroupNameAndParent(t *testing.T) { -+ root, err := getCgroupRoot() -+ if err != nil { -+ t.Errorf("couldn't get cgroup root: %v", err) -+ } -+ -+ config := &configs.Cgroup{ -+ Parent: "../../../../../../../../../../some/path", -+ Name: "../../../../../../../../../../some/path", -+ } -+ -+ data, err := getCgroupData(config, 0) -+ if err != nil { -+ t.Errorf("couldn't get cgroup data: %v", err) -+ } -+ -+ // Make sure the final innerPath doesn't go outside the cgroup mountpoint. -+ if strings.HasPrefix(data.innerPath, "..") { -+ t.Errorf("SECURITY: cgroup innerPath is outside cgroup mountpoint!") -+ } -+ -+ // Double-check, using an actual cgroup. -+ deviceRoot := filepath.Join(root, "devices") -+ devicePath, err := data.path("devices") -+ if err != nil { -+ t.Errorf("couldn't get cgroup path: %v", err) -+ } -+ if !strings.HasPrefix(devicePath, deviceRoot) { -+ t.Errorf("SECURITY: cgroup path() is outside cgroup mountpoint!") -+ } -+} -+ -+// XXX: Remove me after we get rid of configs.Cgroup.Name and configs.Cgroup.Parent. -+func TestInvalidAbsoluteCgroupNameAndParent(t *testing.T) { -+ root, err := getCgroupRoot() -+ if err != nil { -+ t.Errorf("couldn't get cgroup root: %v", err) -+ } -+ -+ config := &configs.Cgroup{ -+ Parent: "/../../../../../../../../../../some/path", -+ Name: "/../../../../../../../../../../some/path", -+ } -+ -+ data, err := getCgroupData(config, 0) -+ if err != nil { -+ t.Errorf("couldn't get cgroup data: %v", err) -+ } -+ -+ // Make sure the final innerPath doesn't go outside the cgroup mountpoint. -+ if strings.HasPrefix(data.innerPath, "..") { -+ t.Errorf("SECURITY: cgroup innerPath is outside cgroup mountpoint!") -+ } -+ -+ // Double-check, using an actual cgroup. -+ deviceRoot := filepath.Join(root, "devices") -+ devicePath, err := data.path("devices") -+ if err != nil { -+ t.Errorf("couldn't get cgroup path: %v", err) -+ } -+ if !strings.HasPrefix(devicePath, deviceRoot) { -+ t.Errorf("SECURITY: cgroup path() is outside cgroup mountpoint!") -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go -new file mode 100644 -index 0000000000..a142cb991d ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio.go -@@ -0,0 +1,237 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "bufio" -+ "fmt" -+ "os" -+ "path/filepath" -+ "strconv" -+ "strings" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+type BlkioGroup struct { -+} -+ -+func (s *BlkioGroup) Name() string { -+ return "blkio" -+} -+ -+func (s *BlkioGroup) Apply(d *cgroupData) error { -+ _, err := d.join("blkio") -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ return nil -+} -+ -+func (s *BlkioGroup) Set(path string, cgroup *configs.Cgroup) error { -+ if cgroup.Resources.BlkioWeight != 0 { -+ if err := writeFile(path, "blkio.weight", strconv.FormatUint(uint64(cgroup.Resources.BlkioWeight), 10)); err != nil { -+ return err -+ } -+ } -+ -+ if cgroup.Resources.BlkioLeafWeight != 0 { -+ if err := writeFile(path, "blkio.leaf_weight", strconv.FormatUint(uint64(cgroup.Resources.BlkioLeafWeight), 10)); err != nil { -+ return err -+ } -+ } -+ for _, wd := range cgroup.Resources.BlkioWeightDevice { -+ if err := writeFile(path, "blkio.weight_device", wd.WeightString()); err != nil { -+ return err -+ } -+ if err := writeFile(path, "blkio.leaf_weight_device", wd.LeafWeightString()); err != nil { -+ return err -+ } -+ } -+ for _, td := range cgroup.Resources.BlkioThrottleReadBpsDevice { -+ if err := writeFile(path, "blkio.throttle.read_bps_device", td.String()); err != nil { -+ return err -+ } -+ } -+ for _, td := range cgroup.Resources.BlkioThrottleWriteBpsDevice { -+ if err := writeFile(path, "blkio.throttle.write_bps_device", td.String()); err != nil { -+ return err -+ } -+ } -+ for _, td := range cgroup.Resources.BlkioThrottleReadIOPSDevice { -+ if err := writeFile(path, "blkio.throttle.read_iops_device", td.String()); err != nil { -+ return err -+ } -+ } -+ for _, td := range cgroup.Resources.BlkioThrottleWriteIOPSDevice { -+ if err := writeFile(path, "blkio.throttle.write_iops_device", td.String()); err != nil { -+ return err -+ } -+ } -+ -+ return nil -+} -+ -+func (s *BlkioGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("blkio")) -+} -+ -+/* -+examples: -+ -+ blkio.sectors -+ 8:0 6792 -+ -+ blkio.io_service_bytes -+ 8:0 Read 1282048 -+ 8:0 Write 2195456 -+ 8:0 Sync 2195456 -+ 8:0 Async 1282048 -+ 8:0 Total 3477504 -+ Total 3477504 -+ -+ blkio.io_serviced -+ 8:0 Read 124 -+ 8:0 Write 104 -+ 8:0 Sync 104 -+ 8:0 Async 124 -+ 8:0 Total 228 -+ Total 228 -+ -+ blkio.io_queued -+ 8:0 Read 0 -+ 8:0 Write 0 -+ 8:0 Sync 0 -+ 8:0 Async 0 -+ 8:0 Total 0 -+ Total 0 -+*/ -+ -+func splitBlkioStatLine(r rune) bool { -+ return r == ' ' || r == ':' -+} -+ -+func getBlkioStat(path string) ([]cgroups.BlkioStatEntry, error) { -+ var blkioStats []cgroups.BlkioStatEntry -+ f, err := os.Open(path) -+ if err != nil { -+ if os.IsNotExist(err) { -+ return blkioStats, nil -+ } -+ return nil, err -+ } -+ defer f.Close() -+ -+ sc := bufio.NewScanner(f) -+ for sc.Scan() { -+ // format: dev type amount -+ fields := strings.FieldsFunc(sc.Text(), splitBlkioStatLine) -+ if len(fields) < 3 { -+ if len(fields) == 2 && fields[0] == "Total" { -+ // skip total line -+ continue -+ } else { -+ return nil, fmt.Errorf("Invalid line found while parsing %s: %s", path, sc.Text()) -+ } -+ } -+ -+ v, err := strconv.ParseUint(fields[0], 10, 64) -+ if err != nil { -+ return nil, err -+ } -+ major := v -+ -+ v, err = strconv.ParseUint(fields[1], 10, 64) -+ if err != nil { -+ return nil, err -+ } -+ minor := v -+ -+ op := "" -+ valueField := 2 -+ if len(fields) == 4 { -+ op = fields[2] -+ valueField = 3 -+ } -+ v, err = strconv.ParseUint(fields[valueField], 10, 64) -+ if err != nil { -+ return nil, err -+ } -+ blkioStats = append(blkioStats, cgroups.BlkioStatEntry{Major: major, Minor: minor, Op: op, Value: v}) -+ } -+ -+ return blkioStats, nil -+} -+ -+func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error { -+ // Try to read CFQ stats available on all CFQ enabled kernels first -+ if blkioStats, err := getBlkioStat(filepath.Join(path, "blkio.io_serviced_recursive")); err == nil && blkioStats != nil { -+ return getCFQStats(path, stats) -+ } -+ return getStats(path, stats) // Use generic stats as fallback -+} -+ -+func getCFQStats(path string, stats *cgroups.Stats) error { -+ var blkioStats []cgroups.BlkioStatEntry -+ var err error -+ -+ if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.sectors_recursive")); err != nil { -+ return err -+ } -+ stats.BlkioStats.SectorsRecursive = blkioStats -+ -+ if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_service_bytes_recursive")); err != nil { -+ return err -+ } -+ stats.BlkioStats.IoServiceBytesRecursive = blkioStats -+ -+ if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_serviced_recursive")); err != nil { -+ return err -+ } -+ stats.BlkioStats.IoServicedRecursive = blkioStats -+ -+ if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_queued_recursive")); err != nil { -+ return err -+ } -+ stats.BlkioStats.IoQueuedRecursive = blkioStats -+ -+ if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_service_time_recursive")); err != nil { -+ return err -+ } -+ stats.BlkioStats.IoServiceTimeRecursive = blkioStats -+ -+ if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_wait_time_recursive")); err != nil { -+ return err -+ } -+ stats.BlkioStats.IoWaitTimeRecursive = blkioStats -+ -+ if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.io_merged_recursive")); err != nil { -+ return err -+ } -+ stats.BlkioStats.IoMergedRecursive = blkioStats -+ -+ if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.time_recursive")); err != nil { -+ return err -+ } -+ stats.BlkioStats.IoTimeRecursive = blkioStats -+ -+ return nil -+} -+ -+func getStats(path string, stats *cgroups.Stats) error { -+ var blkioStats []cgroups.BlkioStatEntry -+ var err error -+ -+ if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.throttle.io_service_bytes")); err != nil { -+ return err -+ } -+ stats.BlkioStats.IoServiceBytesRecursive = blkioStats -+ -+ if blkioStats, err = getBlkioStat(filepath.Join(path, "blkio.throttle.io_serviced")); err != nil { -+ return err -+ } -+ stats.BlkioStats.IoServicedRecursive = blkioStats -+ -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio_test.go -new file mode 100644 -index 0000000000..6957392048 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/blkio_test.go -@@ -0,0 +1,636 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "strconv" -+ "testing" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+const ( -+ sectorsRecursiveContents = `8:0 1024` -+ serviceBytesRecursiveContents = `8:0 Read 100 -+8:0 Write 200 -+8:0 Sync 300 -+8:0 Async 500 -+8:0 Total 500 -+Total 500` -+ servicedRecursiveContents = `8:0 Read 10 -+8:0 Write 40 -+8:0 Sync 20 -+8:0 Async 30 -+8:0 Total 50 -+Total 50` -+ queuedRecursiveContents = `8:0 Read 1 -+8:0 Write 4 -+8:0 Sync 2 -+8:0 Async 3 -+8:0 Total 5 -+Total 5` -+ serviceTimeRecursiveContents = `8:0 Read 173959 -+8:0 Write 0 -+8:0 Sync 0 -+8:0 Async 173959 -+8:0 Total 17395 -+Total 17395` -+ waitTimeRecursiveContents = `8:0 Read 15571 -+8:0 Write 0 -+8:0 Sync 0 -+8:0 Async 15571 -+8:0 Total 15571` -+ mergedRecursiveContents = `8:0 Read 5 -+8:0 Write 10 -+8:0 Sync 0 -+8:0 Async 0 -+8:0 Total 15 -+Total 15` -+ timeRecursiveContents = `8:0 8` -+ throttleServiceBytes = `8:0 Read 11030528 -+8:0 Write 23 -+8:0 Sync 42 -+8:0 Async 11030528 -+8:0 Total 11030528 -+252:0 Read 11030528 -+252:0 Write 23 -+252:0 Sync 42 -+252:0 Async 11030528 -+252:0 Total 11030528 -+Total 22061056` -+ throttleServiced = `8:0 Read 164 -+8:0 Write 23 -+8:0 Sync 42 -+8:0 Async 164 -+8:0 Total 164 -+252:0 Read 164 -+252:0 Write 23 -+252:0 Sync 42 -+252:0 Async 164 -+252:0 Total 164 -+Total 328` -+) -+ -+func appendBlkioStatEntry(blkioStatEntries *[]cgroups.BlkioStatEntry, major, minor, value uint64, op string) { -+ *blkioStatEntries = append(*blkioStatEntries, cgroups.BlkioStatEntry{Major: major, Minor: minor, Value: value, Op: op}) -+} -+ -+func TestBlkioSetWeight(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ -+ const ( -+ weightBefore = 100 -+ weightAfter = 200 -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "blkio.weight": strconv.Itoa(weightBefore), -+ }) -+ -+ helper.CgroupData.config.Resources.BlkioWeight = weightAfter -+ blkio := &BlkioGroup{} -+ if err := blkio.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamUint(helper.CgroupPath, "blkio.weight") -+ if err != nil { -+ t.Fatalf("Failed to parse blkio.weight - %s", err) -+ } -+ -+ if value != weightAfter { -+ t.Fatal("Got the wrong value, set blkio.weight failed.") -+ } -+} -+ -+func TestBlkioSetWeightDevice(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ -+ const ( -+ weightDeviceBefore = "8:0 400" -+ ) -+ -+ wd := configs.NewWeightDevice(8, 0, 500, 0) -+ weightDeviceAfter := wd.WeightString() -+ -+ helper.writeFileContents(map[string]string{ -+ "blkio.weight_device": weightDeviceBefore, -+ }) -+ -+ helper.CgroupData.config.Resources.BlkioWeightDevice = []*configs.WeightDevice{wd} -+ blkio := &BlkioGroup{} -+ if err := blkio.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "blkio.weight_device") -+ if err != nil { -+ t.Fatalf("Failed to parse blkio.weight_device - %s", err) -+ } -+ -+ if value != weightDeviceAfter { -+ t.Fatal("Got the wrong value, set blkio.weight_device failed.") -+ } -+} -+ -+// regression #274 -+func TestBlkioSetMultipleWeightDevice(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ -+ const ( -+ weightDeviceBefore = "8:0 400" -+ ) -+ -+ wd1 := configs.NewWeightDevice(8, 0, 500, 0) -+ wd2 := configs.NewWeightDevice(8, 16, 500, 0) -+ // we cannot actually set and check both because normal ioutil.WriteFile -+ // when writing to cgroup file will overwrite the whole file content instead -+ // of updating it as the kernel is doing. Just check the second device -+ // is present will suffice for the test to ensure multiple writes are done. -+ weightDeviceAfter := wd2.WeightString() -+ -+ helper.writeFileContents(map[string]string{ -+ "blkio.weight_device": weightDeviceBefore, -+ }) -+ -+ helper.CgroupData.config.Resources.BlkioWeightDevice = []*configs.WeightDevice{wd1, wd2} -+ blkio := &BlkioGroup{} -+ if err := blkio.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "blkio.weight_device") -+ if err != nil { -+ t.Fatalf("Failed to parse blkio.weight_device - %s", err) -+ } -+ -+ if value != weightDeviceAfter { -+ t.Fatal("Got the wrong value, set blkio.weight_device failed.") -+ } -+} -+ -+func TestBlkioStats(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "blkio.io_service_bytes_recursive": serviceBytesRecursiveContents, -+ "blkio.io_serviced_recursive": servicedRecursiveContents, -+ "blkio.io_queued_recursive": queuedRecursiveContents, -+ "blkio.io_service_time_recursive": serviceTimeRecursiveContents, -+ "blkio.io_wait_time_recursive": waitTimeRecursiveContents, -+ "blkio.io_merged_recursive": mergedRecursiveContents, -+ "blkio.time_recursive": timeRecursiveContents, -+ "blkio.sectors_recursive": sectorsRecursiveContents, -+ }) -+ -+ blkio := &BlkioGroup{} -+ actualStats := *cgroups.NewStats() -+ err := blkio.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatal(err) -+ } -+ -+ // Verify expected stats. -+ expectedStats := cgroups.BlkioStats{} -+ appendBlkioStatEntry(&expectedStats.SectorsRecursive, 8, 0, 1024, "") -+ -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 100, "Read") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 200, "Write") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 300, "Sync") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 500, "Async") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 500, "Total") -+ -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 10, "Read") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 40, "Write") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 20, "Sync") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 30, "Async") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 50, "Total") -+ -+ appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 1, "Read") -+ appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 4, "Write") -+ appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 2, "Sync") -+ appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 3, "Async") -+ appendBlkioStatEntry(&expectedStats.IoQueuedRecursive, 8, 0, 5, "Total") -+ -+ appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 173959, "Read") -+ appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 0, "Write") -+ appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 0, "Sync") -+ appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 173959, "Async") -+ appendBlkioStatEntry(&expectedStats.IoServiceTimeRecursive, 8, 0, 17395, "Total") -+ -+ appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 15571, "Read") -+ appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 0, "Write") -+ appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 0, "Sync") -+ appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 15571, "Async") -+ appendBlkioStatEntry(&expectedStats.IoWaitTimeRecursive, 8, 0, 15571, "Total") -+ -+ appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 5, "Read") -+ appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 10, "Write") -+ appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 0, "Sync") -+ appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 0, "Async") -+ appendBlkioStatEntry(&expectedStats.IoMergedRecursive, 8, 0, 15, "Total") -+ -+ appendBlkioStatEntry(&expectedStats.IoTimeRecursive, 8, 0, 8, "") -+ -+ expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats) -+} -+ -+func TestBlkioStatsNoSectorsFile(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "blkio.io_service_bytes_recursive": serviceBytesRecursiveContents, -+ "blkio.io_serviced_recursive": servicedRecursiveContents, -+ "blkio.io_queued_recursive": queuedRecursiveContents, -+ "blkio.io_service_time_recursive": serviceTimeRecursiveContents, -+ "blkio.io_wait_time_recursive": waitTimeRecursiveContents, -+ "blkio.io_merged_recursive": mergedRecursiveContents, -+ "blkio.time_recursive": timeRecursiveContents, -+ }) -+ -+ blkio := &BlkioGroup{} -+ actualStats := *cgroups.NewStats() -+ err := blkio.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatalf("Failed unexpectedly: %s", err) -+ } -+} -+ -+func TestBlkioStatsNoServiceBytesFile(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "blkio.io_serviced_recursive": servicedRecursiveContents, -+ "blkio.io_queued_recursive": queuedRecursiveContents, -+ "blkio.sectors_recursive": sectorsRecursiveContents, -+ "blkio.io_service_time_recursive": serviceTimeRecursiveContents, -+ "blkio.io_wait_time_recursive": waitTimeRecursiveContents, -+ "blkio.io_merged_recursive": mergedRecursiveContents, -+ "blkio.time_recursive": timeRecursiveContents, -+ }) -+ -+ blkio := &BlkioGroup{} -+ actualStats := *cgroups.NewStats() -+ err := blkio.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatalf("Failed unexpectedly: %s", err) -+ } -+} -+ -+func TestBlkioStatsNoServicedFile(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "blkio.io_service_bytes_recursive": serviceBytesRecursiveContents, -+ "blkio.io_queued_recursive": queuedRecursiveContents, -+ "blkio.sectors_recursive": sectorsRecursiveContents, -+ "blkio.io_service_time_recursive": serviceTimeRecursiveContents, -+ "blkio.io_wait_time_recursive": waitTimeRecursiveContents, -+ "blkio.io_merged_recursive": mergedRecursiveContents, -+ "blkio.time_recursive": timeRecursiveContents, -+ }) -+ -+ blkio := &BlkioGroup{} -+ actualStats := *cgroups.NewStats() -+ err := blkio.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatalf("Failed unexpectedly: %s", err) -+ } -+} -+ -+func TestBlkioStatsNoQueuedFile(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "blkio.io_service_bytes_recursive": serviceBytesRecursiveContents, -+ "blkio.io_serviced_recursive": servicedRecursiveContents, -+ "blkio.sectors_recursive": sectorsRecursiveContents, -+ "blkio.io_service_time_recursive": serviceTimeRecursiveContents, -+ "blkio.io_wait_time_recursive": waitTimeRecursiveContents, -+ "blkio.io_merged_recursive": mergedRecursiveContents, -+ "blkio.time_recursive": timeRecursiveContents, -+ }) -+ -+ blkio := &BlkioGroup{} -+ actualStats := *cgroups.NewStats() -+ err := blkio.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatalf("Failed unexpectedly: %s", err) -+ } -+} -+ -+func TestBlkioStatsNoServiceTimeFile(t *testing.T) { -+ if testing.Short() { -+ t.Skip("skipping test in short mode.") -+ } -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "blkio.io_service_bytes_recursive": serviceBytesRecursiveContents, -+ "blkio.io_serviced_recursive": servicedRecursiveContents, -+ "blkio.io_queued_recursive": queuedRecursiveContents, -+ "blkio.io_wait_time_recursive": waitTimeRecursiveContents, -+ "blkio.io_merged_recursive": mergedRecursiveContents, -+ "blkio.time_recursive": timeRecursiveContents, -+ "blkio.sectors_recursive": sectorsRecursiveContents, -+ }) -+ -+ blkio := &BlkioGroup{} -+ actualStats := *cgroups.NewStats() -+ err := blkio.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatalf("Failed unexpectedly: %s", err) -+ } -+} -+ -+func TestBlkioStatsNoWaitTimeFile(t *testing.T) { -+ if testing.Short() { -+ t.Skip("skipping test in short mode.") -+ } -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "blkio.io_service_bytes_recursive": serviceBytesRecursiveContents, -+ "blkio.io_serviced_recursive": servicedRecursiveContents, -+ "blkio.io_queued_recursive": queuedRecursiveContents, -+ "blkio.io_service_time_recursive": serviceTimeRecursiveContents, -+ "blkio.io_merged_recursive": mergedRecursiveContents, -+ "blkio.time_recursive": timeRecursiveContents, -+ "blkio.sectors_recursive": sectorsRecursiveContents, -+ }) -+ -+ blkio := &BlkioGroup{} -+ actualStats := *cgroups.NewStats() -+ err := blkio.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatalf("Failed unexpectedly: %s", err) -+ } -+} -+ -+func TestBlkioStatsNoMergedFile(t *testing.T) { -+ if testing.Short() { -+ t.Skip("skipping test in short mode.") -+ } -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "blkio.io_service_bytes_recursive": serviceBytesRecursiveContents, -+ "blkio.io_serviced_recursive": servicedRecursiveContents, -+ "blkio.io_queued_recursive": queuedRecursiveContents, -+ "blkio.io_service_time_recursive": serviceTimeRecursiveContents, -+ "blkio.io_wait_time_recursive": waitTimeRecursiveContents, -+ "blkio.time_recursive": timeRecursiveContents, -+ "blkio.sectors_recursive": sectorsRecursiveContents, -+ }) -+ -+ blkio := &BlkioGroup{} -+ actualStats := *cgroups.NewStats() -+ err := blkio.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatalf("Failed unexpectedly: %s", err) -+ } -+} -+ -+func TestBlkioStatsNoTimeFile(t *testing.T) { -+ if testing.Short() { -+ t.Skip("skipping test in short mode.") -+ } -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "blkio.io_service_bytes_recursive": serviceBytesRecursiveContents, -+ "blkio.io_serviced_recursive": servicedRecursiveContents, -+ "blkio.io_queued_recursive": queuedRecursiveContents, -+ "blkio.io_service_time_recursive": serviceTimeRecursiveContents, -+ "blkio.io_wait_time_recursive": waitTimeRecursiveContents, -+ "blkio.io_merged_recursive": mergedRecursiveContents, -+ "blkio.sectors_recursive": sectorsRecursiveContents, -+ }) -+ -+ blkio := &BlkioGroup{} -+ actualStats := *cgroups.NewStats() -+ err := blkio.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatalf("Failed unexpectedly: %s", err) -+ } -+} -+ -+func TestBlkioStatsUnexpectedNumberOfFields(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "blkio.io_service_bytes_recursive": "8:0 Read 100 100", -+ "blkio.io_serviced_recursive": servicedRecursiveContents, -+ "blkio.io_queued_recursive": queuedRecursiveContents, -+ "blkio.sectors_recursive": sectorsRecursiveContents, -+ "blkio.io_service_time_recursive": serviceTimeRecursiveContents, -+ "blkio.io_wait_time_recursive": waitTimeRecursiveContents, -+ "blkio.io_merged_recursive": mergedRecursiveContents, -+ "blkio.time_recursive": timeRecursiveContents, -+ }) -+ -+ blkio := &BlkioGroup{} -+ actualStats := *cgroups.NewStats() -+ err := blkio.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected to fail, but did not") -+ } -+} -+ -+func TestBlkioStatsUnexpectedFieldType(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "blkio.io_service_bytes_recursive": "8:0 Read Write", -+ "blkio.io_serviced_recursive": servicedRecursiveContents, -+ "blkio.io_queued_recursive": queuedRecursiveContents, -+ "blkio.sectors_recursive": sectorsRecursiveContents, -+ "blkio.io_service_time_recursive": serviceTimeRecursiveContents, -+ "blkio.io_wait_time_recursive": waitTimeRecursiveContents, -+ "blkio.io_merged_recursive": mergedRecursiveContents, -+ "blkio.time_recursive": timeRecursiveContents, -+ }) -+ -+ blkio := &BlkioGroup{} -+ actualStats := *cgroups.NewStats() -+ err := blkio.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected to fail, but did not") -+ } -+} -+ -+func TestNonCFQBlkioStats(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "blkio.io_service_bytes_recursive": "", -+ "blkio.io_serviced_recursive": "", -+ "blkio.io_queued_recursive": "", -+ "blkio.sectors_recursive": "", -+ "blkio.io_service_time_recursive": "", -+ "blkio.io_wait_time_recursive": "", -+ "blkio.io_merged_recursive": "", -+ "blkio.time_recursive": "", -+ "blkio.throttle.io_service_bytes": throttleServiceBytes, -+ "blkio.throttle.io_serviced": throttleServiced, -+ }) -+ -+ blkio := &BlkioGroup{} -+ actualStats := *cgroups.NewStats() -+ err := blkio.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatal(err) -+ } -+ -+ // Verify expected stats. -+ expectedStats := cgroups.BlkioStats{} -+ -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 11030528, "Read") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 23, "Write") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 42, "Sync") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 11030528, "Async") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 8, 0, 11030528, "Total") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 11030528, "Read") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 23, "Write") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 42, "Sync") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 11030528, "Async") -+ appendBlkioStatEntry(&expectedStats.IoServiceBytesRecursive, 252, 0, 11030528, "Total") -+ -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 164, "Read") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 23, "Write") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 42, "Sync") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 164, "Async") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 8, 0, 164, "Total") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 164, "Read") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 23, "Write") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 42, "Sync") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 164, "Async") -+ appendBlkioStatEntry(&expectedStats.IoServicedRecursive, 252, 0, 164, "Total") -+ -+ expectBlkioStatsEquals(t, expectedStats, actualStats.BlkioStats) -+} -+ -+func TestBlkioSetThrottleReadBpsDevice(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ -+ const ( -+ throttleBefore = `8:0 1024` -+ ) -+ -+ td := configs.NewThrottleDevice(8, 0, 2048) -+ throttleAfter := td.String() -+ -+ helper.writeFileContents(map[string]string{ -+ "blkio.throttle.read_bps_device": throttleBefore, -+ }) -+ -+ helper.CgroupData.config.Resources.BlkioThrottleReadBpsDevice = []*configs.ThrottleDevice{td} -+ blkio := &BlkioGroup{} -+ if err := blkio.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "blkio.throttle.read_bps_device") -+ if err != nil { -+ t.Fatalf("Failed to parse blkio.throttle.read_bps_device - %s", err) -+ } -+ -+ if value != throttleAfter { -+ t.Fatal("Got the wrong value, set blkio.throttle.read_bps_device failed.") -+ } -+} -+func TestBlkioSetThrottleWriteBpsDevice(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ -+ const ( -+ throttleBefore = `8:0 1024` -+ ) -+ -+ td := configs.NewThrottleDevice(8, 0, 2048) -+ throttleAfter := td.String() -+ -+ helper.writeFileContents(map[string]string{ -+ "blkio.throttle.write_bps_device": throttleBefore, -+ }) -+ -+ helper.CgroupData.config.Resources.BlkioThrottleWriteBpsDevice = []*configs.ThrottleDevice{td} -+ blkio := &BlkioGroup{} -+ if err := blkio.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "blkio.throttle.write_bps_device") -+ if err != nil { -+ t.Fatalf("Failed to parse blkio.throttle.write_bps_device - %s", err) -+ } -+ -+ if value != throttleAfter { -+ t.Fatal("Got the wrong value, set blkio.throttle.write_bps_device failed.") -+ } -+} -+func TestBlkioSetThrottleReadIOpsDevice(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ -+ const ( -+ throttleBefore = `8:0 1024` -+ ) -+ -+ td := configs.NewThrottleDevice(8, 0, 2048) -+ throttleAfter := td.String() -+ -+ helper.writeFileContents(map[string]string{ -+ "blkio.throttle.read_iops_device": throttleBefore, -+ }) -+ -+ helper.CgroupData.config.Resources.BlkioThrottleReadIOPSDevice = []*configs.ThrottleDevice{td} -+ blkio := &BlkioGroup{} -+ if err := blkio.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "blkio.throttle.read_iops_device") -+ if err != nil { -+ t.Fatalf("Failed to parse blkio.throttle.read_iops_device - %s", err) -+ } -+ -+ if value != throttleAfter { -+ t.Fatal("Got the wrong value, set blkio.throttle.read_iops_device failed.") -+ } -+} -+func TestBlkioSetThrottleWriteIOpsDevice(t *testing.T) { -+ helper := NewCgroupTestUtil("blkio", t) -+ defer helper.cleanup() -+ -+ const ( -+ throttleBefore = `8:0 1024` -+ ) -+ -+ td := configs.NewThrottleDevice(8, 0, 2048) -+ throttleAfter := td.String() -+ -+ helper.writeFileContents(map[string]string{ -+ "blkio.throttle.write_iops_device": throttleBefore, -+ }) -+ -+ helper.CgroupData.config.Resources.BlkioThrottleWriteIOPSDevice = []*configs.ThrottleDevice{td} -+ blkio := &BlkioGroup{} -+ if err := blkio.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "blkio.throttle.write_iops_device") -+ if err != nil { -+ t.Fatalf("Failed to parse blkio.throttle.write_iops_device - %s", err) -+ } -+ -+ if value != throttleAfter { -+ t.Fatal("Got the wrong value, set blkio.throttle.write_iops_device failed.") -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go -new file mode 100644 -index 0000000000..b712bd0b1e ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu.go -@@ -0,0 +1,125 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "bufio" -+ "os" -+ "path/filepath" -+ "strconv" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+type CpuGroup struct { -+} -+ -+func (s *CpuGroup) Name() string { -+ return "cpu" -+} -+ -+func (s *CpuGroup) Apply(d *cgroupData) error { -+ // We always want to join the cpu group, to allow fair cpu scheduling -+ // on a container basis -+ path, err := d.path("cpu") -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ return s.ApplyDir(path, d.config, d.pid) -+} -+ -+func (s *CpuGroup) ApplyDir(path string, cgroup *configs.Cgroup, pid int) error { -+ // This might happen if we have no cpu cgroup mounted. -+ // Just do nothing and don't fail. -+ if path == "" { -+ return nil -+ } -+ if err := os.MkdirAll(path, 0755); err != nil { -+ return err -+ } -+ // We should set the real-Time group scheduling settings before moving -+ // in the process because if the process is already in SCHED_RR mode -+ // and no RT bandwidth is set, adding it will fail. -+ if err := s.SetRtSched(path, cgroup); err != nil { -+ return err -+ } -+ // because we are not using d.join we need to place the pid into the procs file -+ // unlike the other subsystems -+ if err := cgroups.WriteCgroupProc(path, pid); err != nil { -+ return err -+ } -+ -+ return nil -+} -+ -+func (s *CpuGroup) SetRtSched(path string, cgroup *configs.Cgroup) error { -+ if cgroup.Resources.CpuRtPeriod != 0 { -+ if err := writeFile(path, "cpu.rt_period_us", strconv.FormatUint(cgroup.Resources.CpuRtPeriod, 10)); err != nil { -+ return err -+ } -+ } -+ if cgroup.Resources.CpuRtRuntime != 0 { -+ if err := writeFile(path, "cpu.rt_runtime_us", strconv.FormatInt(cgroup.Resources.CpuRtRuntime, 10)); err != nil { -+ return err -+ } -+ } -+ return nil -+} -+ -+func (s *CpuGroup) Set(path string, cgroup *configs.Cgroup) error { -+ if cgroup.Resources.CpuShares != 0 { -+ if err := writeFile(path, "cpu.shares", strconv.FormatUint(cgroup.Resources.CpuShares, 10)); err != nil { -+ return err -+ } -+ } -+ if cgroup.Resources.CpuPeriod != 0 { -+ if err := writeFile(path, "cpu.cfs_period_us", strconv.FormatUint(cgroup.Resources.CpuPeriod, 10)); err != nil { -+ return err -+ } -+ } -+ if cgroup.Resources.CpuQuota != 0 { -+ if err := writeFile(path, "cpu.cfs_quota_us", strconv.FormatInt(cgroup.Resources.CpuQuota, 10)); err != nil { -+ return err -+ } -+ } -+ if err := s.SetRtSched(path, cgroup); err != nil { -+ return err -+ } -+ -+ return nil -+} -+ -+func (s *CpuGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("cpu")) -+} -+ -+func (s *CpuGroup) GetStats(path string, stats *cgroups.Stats) error { -+ f, err := os.Open(filepath.Join(path, "cpu.stat")) -+ if err != nil { -+ if os.IsNotExist(err) { -+ return nil -+ } -+ return err -+ } -+ defer f.Close() -+ -+ sc := bufio.NewScanner(f) -+ for sc.Scan() { -+ t, v, err := getCgroupParamKeyValue(sc.Text()) -+ if err != nil { -+ return err -+ } -+ switch t { -+ case "nr_periods": -+ stats.CpuStats.ThrottlingData.Periods = v -+ -+ case "nr_throttled": -+ stats.CpuStats.ThrottlingData.ThrottledPeriods = v -+ -+ case "throttled_time": -+ stats.CpuStats.ThrottlingData.ThrottledTime = v -+ } -+ } -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu_test.go -new file mode 100644 -index 0000000000..6369c91ad6 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpu_test.go -@@ -0,0 +1,209 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "fmt" -+ "strconv" -+ "testing" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+) -+ -+func TestCpuSetShares(t *testing.T) { -+ helper := NewCgroupTestUtil("cpu", t) -+ defer helper.cleanup() -+ -+ const ( -+ sharesBefore = 1024 -+ sharesAfter = 512 -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "cpu.shares": strconv.Itoa(sharesBefore), -+ }) -+ -+ helper.CgroupData.config.Resources.CpuShares = sharesAfter -+ cpu := &CpuGroup{} -+ if err := cpu.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamUint(helper.CgroupPath, "cpu.shares") -+ if err != nil { -+ t.Fatalf("Failed to parse cpu.shares - %s", err) -+ } -+ -+ if value != sharesAfter { -+ t.Fatal("Got the wrong value, set cpu.shares failed.") -+ } -+} -+ -+func TestCpuSetBandWidth(t *testing.T) { -+ helper := NewCgroupTestUtil("cpu", t) -+ defer helper.cleanup() -+ -+ const ( -+ quotaBefore = 8000 -+ quotaAfter = 5000 -+ periodBefore = 10000 -+ periodAfter = 7000 -+ rtRuntimeBefore = 8000 -+ rtRuntimeAfter = 5000 -+ rtPeriodBefore = 10000 -+ rtPeriodAfter = 7000 -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "cpu.cfs_quota_us": strconv.Itoa(quotaBefore), -+ "cpu.cfs_period_us": strconv.Itoa(periodBefore), -+ "cpu.rt_runtime_us": strconv.Itoa(rtRuntimeBefore), -+ "cpu.rt_period_us": strconv.Itoa(rtPeriodBefore), -+ }) -+ -+ helper.CgroupData.config.Resources.CpuQuota = quotaAfter -+ helper.CgroupData.config.Resources.CpuPeriod = periodAfter -+ helper.CgroupData.config.Resources.CpuRtRuntime = rtRuntimeAfter -+ helper.CgroupData.config.Resources.CpuRtPeriod = rtPeriodAfter -+ cpu := &CpuGroup{} -+ if err := cpu.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ quota, err := getCgroupParamUint(helper.CgroupPath, "cpu.cfs_quota_us") -+ if err != nil { -+ t.Fatalf("Failed to parse cpu.cfs_quota_us - %s", err) -+ } -+ if quota != quotaAfter { -+ t.Fatal("Got the wrong value, set cpu.cfs_quota_us failed.") -+ } -+ -+ period, err := getCgroupParamUint(helper.CgroupPath, "cpu.cfs_period_us") -+ if err != nil { -+ t.Fatalf("Failed to parse cpu.cfs_period_us - %s", err) -+ } -+ if period != periodAfter { -+ t.Fatal("Got the wrong value, set cpu.cfs_period_us failed.") -+ } -+ rtRuntime, err := getCgroupParamUint(helper.CgroupPath, "cpu.rt_runtime_us") -+ if err != nil { -+ t.Fatalf("Failed to parse cpu.rt_runtime_us - %s", err) -+ } -+ if rtRuntime != rtRuntimeAfter { -+ t.Fatal("Got the wrong value, set cpu.rt_runtime_us failed.") -+ } -+ rtPeriod, err := getCgroupParamUint(helper.CgroupPath, "cpu.rt_period_us") -+ if err != nil { -+ t.Fatalf("Failed to parse cpu.rt_period_us - %s", err) -+ } -+ if rtPeriod != rtPeriodAfter { -+ t.Fatal("Got the wrong value, set cpu.rt_period_us failed.") -+ } -+} -+ -+func TestCpuStats(t *testing.T) { -+ helper := NewCgroupTestUtil("cpu", t) -+ defer helper.cleanup() -+ -+ const ( -+ nrPeriods = 2000 -+ nrThrottled = 200 -+ throttledTime = uint64(18446744073709551615) -+ ) -+ -+ cpuStatContent := fmt.Sprintf("nr_periods %d\n nr_throttled %d\n throttled_time %d\n", -+ nrPeriods, nrThrottled, throttledTime) -+ helper.writeFileContents(map[string]string{ -+ "cpu.stat": cpuStatContent, -+ }) -+ -+ cpu := &CpuGroup{} -+ actualStats := *cgroups.NewStats() -+ err := cpu.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatal(err) -+ } -+ -+ expectedStats := cgroups.ThrottlingData{ -+ Periods: nrPeriods, -+ ThrottledPeriods: nrThrottled, -+ ThrottledTime: throttledTime} -+ -+ expectThrottlingDataEquals(t, expectedStats, actualStats.CpuStats.ThrottlingData) -+} -+ -+func TestNoCpuStatFile(t *testing.T) { -+ helper := NewCgroupTestUtil("cpu", t) -+ defer helper.cleanup() -+ -+ cpu := &CpuGroup{} -+ actualStats := *cgroups.NewStats() -+ err := cpu.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatal("Expected not to fail, but did") -+ } -+} -+ -+func TestInvalidCpuStat(t *testing.T) { -+ helper := NewCgroupTestUtil("cpu", t) -+ defer helper.cleanup() -+ cpuStatContent := `nr_periods 2000 -+ nr_throttled 200 -+ throttled_time fortytwo` -+ helper.writeFileContents(map[string]string{ -+ "cpu.stat": cpuStatContent, -+ }) -+ -+ cpu := &CpuGroup{} -+ actualStats := *cgroups.NewStats() -+ err := cpu.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected failed stat parsing.") -+ } -+} -+ -+func TestCpuSetRtSchedAtApply(t *testing.T) { -+ helper := NewCgroupTestUtil("cpu", t) -+ defer helper.cleanup() -+ -+ const ( -+ rtRuntimeBefore = 0 -+ rtRuntimeAfter = 5000 -+ rtPeriodBefore = 0 -+ rtPeriodAfter = 7000 -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "cpu.rt_runtime_us": strconv.Itoa(rtRuntimeBefore), -+ "cpu.rt_period_us": strconv.Itoa(rtPeriodBefore), -+ }) -+ -+ helper.CgroupData.config.Resources.CpuRtRuntime = rtRuntimeAfter -+ helper.CgroupData.config.Resources.CpuRtPeriod = rtPeriodAfter -+ cpu := &CpuGroup{} -+ if err := cpu.ApplyDir(helper.CgroupPath, helper.CgroupData.config, 1234); err != nil { -+ t.Fatal(err) -+ } -+ -+ rtRuntime, err := getCgroupParamUint(helper.CgroupPath, "cpu.rt_runtime_us") -+ if err != nil { -+ t.Fatalf("Failed to parse cpu.rt_runtime_us - %s", err) -+ } -+ if rtRuntime != rtRuntimeAfter { -+ t.Fatal("Got the wrong value, set cpu.rt_runtime_us failed.") -+ } -+ rtPeriod, err := getCgroupParamUint(helper.CgroupPath, "cpu.rt_period_us") -+ if err != nil { -+ t.Fatalf("Failed to parse cpu.rt_period_us - %s", err) -+ } -+ if rtPeriod != rtPeriodAfter { -+ t.Fatal("Got the wrong value, set cpu.rt_period_us failed.") -+ } -+ pid, err := getCgroupParamUint(helper.CgroupPath, "cgroup.procs") -+ if err != nil { -+ t.Fatalf("Failed to parse cgroup.procs - %s", err) -+ } -+ if pid != 1234 { -+ t.Fatal("Got the wrong value, set cgroup.procs failed.") -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go -new file mode 100644 -index 0000000000..53afbaddf1 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuacct.go -@@ -0,0 +1,121 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "fmt" -+ "io/ioutil" -+ "path/filepath" -+ "strconv" -+ "strings" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+ "github.com/opencontainers/runc/libcontainer/system" -+) -+ -+const ( -+ cgroupCpuacctStat = "cpuacct.stat" -+ nanosecondsInSecond = 1000000000 -+) -+ -+var clockTicks = uint64(system.GetClockTicks()) -+ -+type CpuacctGroup struct { -+} -+ -+func (s *CpuacctGroup) Name() string { -+ return "cpuacct" -+} -+ -+func (s *CpuacctGroup) Apply(d *cgroupData) error { -+ // we just want to join this group even though we don't set anything -+ if _, err := d.join("cpuacct"); err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ -+ return nil -+} -+ -+func (s *CpuacctGroup) Set(path string, cgroup *configs.Cgroup) error { -+ return nil -+} -+ -+func (s *CpuacctGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("cpuacct")) -+} -+ -+func (s *CpuacctGroup) GetStats(path string, stats *cgroups.Stats) error { -+ userModeUsage, kernelModeUsage, err := getCpuUsageBreakdown(path) -+ if err != nil { -+ return err -+ } -+ -+ totalUsage, err := getCgroupParamUint(path, "cpuacct.usage") -+ if err != nil { -+ return err -+ } -+ -+ percpuUsage, err := getPercpuUsage(path) -+ if err != nil { -+ return err -+ } -+ -+ stats.CpuStats.CpuUsage.TotalUsage = totalUsage -+ stats.CpuStats.CpuUsage.PercpuUsage = percpuUsage -+ stats.CpuStats.CpuUsage.UsageInUsermode = userModeUsage -+ stats.CpuStats.CpuUsage.UsageInKernelmode = kernelModeUsage -+ return nil -+} -+ -+// Returns user and kernel usage breakdown in nanoseconds. -+func getCpuUsageBreakdown(path string) (uint64, uint64, error) { -+ userModeUsage := uint64(0) -+ kernelModeUsage := uint64(0) -+ const ( -+ userField = "user" -+ systemField = "system" -+ ) -+ -+ // Expected format: -+ // user -+ // system -+ data, err := ioutil.ReadFile(filepath.Join(path, cgroupCpuacctStat)) -+ if err != nil { -+ return 0, 0, err -+ } -+ fields := strings.Fields(string(data)) -+ if len(fields) != 4 { -+ return 0, 0, fmt.Errorf("failure - %s is expected to have 4 fields", filepath.Join(path, cgroupCpuacctStat)) -+ } -+ if fields[0] != userField { -+ return 0, 0, fmt.Errorf("unexpected field %q in %q, expected %q", fields[0], cgroupCpuacctStat, userField) -+ } -+ if fields[2] != systemField { -+ return 0, 0, fmt.Errorf("unexpected field %q in %q, expected %q", fields[2], cgroupCpuacctStat, systemField) -+ } -+ if userModeUsage, err = strconv.ParseUint(fields[1], 10, 64); err != nil { -+ return 0, 0, err -+ } -+ if kernelModeUsage, err = strconv.ParseUint(fields[3], 10, 64); err != nil { -+ return 0, 0, err -+ } -+ -+ return (userModeUsage * nanosecondsInSecond) / clockTicks, (kernelModeUsage * nanosecondsInSecond) / clockTicks, nil -+} -+ -+func getPercpuUsage(path string) ([]uint64, error) { -+ percpuUsage := []uint64{} -+ data, err := ioutil.ReadFile(filepath.Join(path, "cpuacct.usage_percpu")) -+ if err != nil { -+ return percpuUsage, err -+ } -+ for _, value := range strings.Fields(string(data)) { -+ value, err := strconv.ParseUint(value, 10, 64) -+ if err != nil { -+ return percpuUsage, fmt.Errorf("Unable to convert param value to uint64: %s", err) -+ } -+ percpuUsage = append(percpuUsage, value) -+ } -+ return percpuUsage, nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go -new file mode 100644 -index 0000000000..e61994fc3c ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset.go -@@ -0,0 +1,183 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "bytes" -+ "fmt" -+ "io/ioutil" -+ "os" -+ "path/filepath" -+ -+ "github.com/sirupsen/logrus" -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+ libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils" -+) -+ -+type CpusetGroup struct { -+} -+ -+func (s *CpusetGroup) Name() string { -+ return "cpuset" -+} -+ -+func (s *CpusetGroup) Apply(d *cgroupData) error { -+ dir, err := d.path("cpuset") -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ return s.ApplyDir(dir, d.config, d.pid) -+} -+ -+func (s *CpusetGroup) Set(path string, cgroup *configs.Cgroup) error { -+ if cgroup.Resources.CpusetCpus != "" { -+ if err := writeFile(path, "cpuset.cpus", cgroup.Resources.CpusetCpus); err != nil { -+ return err -+ } -+ } -+ if cgroup.Resources.CpusetMems != "" { -+ if err := writeFile(path, "cpuset.mems", cgroup.Resources.CpusetMems); err != nil { -+ return err -+ } -+ } -+ return nil -+} -+ -+func (s *CpusetGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("cpuset")) -+} -+ -+func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error { -+ return nil -+} -+ -+func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) error { -+ // This might happen if we have no cpuset cgroup mounted. -+ // Just do nothing and don't fail. -+ if dir == "" { -+ return nil -+ } -+ root, err := getCgroupRoot() -+ if err != nil { -+ return err -+ } -+ // 'ensureParent' start with parent because we don't want to -+ // explicitly inherit from parent, it could conflict with -+ // 'cpuset.cpu_exclusive'. -+ if err := s.ensureParent(filepath.Dir(dir), root); err != nil { -+ return err -+ } -+ if err := os.MkdirAll(dir, 0755); err != nil { -+ return err -+ } -+ // We didn't inherit cpuset configs from parent, but we have -+ // to ensure cpuset configs are set before moving task into the -+ // cgroup. -+ // The logic is, if user specified cpuset configs, use these -+ // specified configs, otherwise, inherit from parent. This makes -+ // cpuset configs work correctly with 'cpuset.cpu_exclusive', and -+ // keep backward compatbility. -+ if err := s.ensureCpusAndMems(dir, cgroup); err != nil { -+ return err -+ } -+ -+ // because we are not using d.join we need to place the pid into the procs file -+ // unlike the other subsystems -+ if err := cgroups.WriteCgroupProc(dir, pid); err != nil { -+ return err -+ } -+ -+ return nil -+} -+ -+func (s *CpusetGroup) getSubsystemSettings(parent string) (cpus []byte, mems []byte, err error) { -+ defer func() { -+ if err != nil { -+ minfo, err1 := ioutil.ReadFile("/proc/self/mountinfo") -+ if err1 != nil { -+ logrus.Errorf("Failed to read mountinfo when getSubsystemSettings get an error") -+ } -+ -+ dirInfo := "" -+ fs, err2 := ioutil.ReadDir(parent) -+ if err2 != nil { -+ logrus.Errorf("Failed to read mountinfo when getSubsystemSettings get an error") -+ } -+ for _, f := range fs { -+ dirInfo = dirInfo + " " + f.Name() -+ } -+ -+ logrus.Errorf("Read cpuset cgroup failed, print mountinfo and cgroup info here"+ -+ "path: %s, mountinfo: [%s], dirinfo: [%s]", parent, string(minfo), dirInfo) -+ } -+ }() -+ if cpus, err = ioutil.ReadFile(filepath.Join(parent, "cpuset.cpus")); err != nil { -+ return -+ } -+ if mems, err = ioutil.ReadFile(filepath.Join(parent, "cpuset.mems")); err != nil { -+ return -+ } -+ return cpus, mems, nil -+} -+ -+// ensureParent makes sure that the parent directory of current is created -+// and populated with the proper cpus and mems files copied from -+// it's parent. -+func (s *CpusetGroup) ensureParent(current, root string) error { -+ parent := filepath.Dir(current) -+ if libcontainerUtils.CleanPath(parent) == root { -+ return nil -+ } -+ // Avoid infinite recursion. -+ if parent == current { -+ return fmt.Errorf("cpuset: cgroup parent path outside cgroup root") -+ } -+ if err := s.ensureParent(parent, root); err != nil { -+ return err -+ } -+ if err := os.MkdirAll(current, 0755); err != nil { -+ return err -+ } -+ return s.copyIfNeeded(current, parent) -+} -+ -+// copyIfNeeded copies the cpuset.cpus and cpuset.mems from the parent -+// directory to the current directory if the file's contents are 0 -+func (s *CpusetGroup) copyIfNeeded(current, parent string) error { -+ var ( -+ err error -+ currentCpus, currentMems []byte -+ parentCpus, parentMems []byte -+ ) -+ -+ if currentCpus, currentMems, err = s.getSubsystemSettings(current); err != nil { -+ return err -+ } -+ if parentCpus, parentMems, err = s.getSubsystemSettings(parent); err != nil { -+ return err -+ } -+ -+ if s.isEmpty(currentCpus) { -+ if err := writeFile(current, "cpuset.cpus", string(parentCpus)); err != nil { -+ return err -+ } -+ } -+ if s.isEmpty(currentMems) { -+ if err := writeFile(current, "cpuset.mems", string(parentMems)); err != nil { -+ return err -+ } -+ } -+ return nil -+} -+ -+func (s *CpusetGroup) isEmpty(b []byte) bool { -+ return len(bytes.Trim(b, "\n")) == 0 -+} -+ -+func (s *CpusetGroup) ensureCpusAndMems(path string, cgroup *configs.Cgroup) error { -+ if err := s.Set(path, cgroup); err != nil { -+ return err -+ } -+ return s.copyIfNeeded(path, filepath.Dir(path)) -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset_test.go -new file mode 100644 -index 0000000000..0f929151fc ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/cpuset_test.go -@@ -0,0 +1,65 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "testing" -+) -+ -+func TestCpusetSetCpus(t *testing.T) { -+ helper := NewCgroupTestUtil("cpuset", t) -+ defer helper.cleanup() -+ -+ const ( -+ cpusBefore = "0" -+ cpusAfter = "1-3" -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "cpuset.cpus": cpusBefore, -+ }) -+ -+ helper.CgroupData.config.Resources.CpusetCpus = cpusAfter -+ cpuset := &CpusetGroup{} -+ if err := cpuset.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "cpuset.cpus") -+ if err != nil { -+ t.Fatalf("Failed to parse cpuset.cpus - %s", err) -+ } -+ -+ if value != cpusAfter { -+ t.Fatal("Got the wrong value, set cpuset.cpus failed.") -+ } -+} -+ -+func TestCpusetSetMems(t *testing.T) { -+ helper := NewCgroupTestUtil("cpuset", t) -+ defer helper.cleanup() -+ -+ const ( -+ memsBefore = "0" -+ memsAfter = "1" -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "cpuset.mems": memsBefore, -+ }) -+ -+ helper.CgroupData.config.Resources.CpusetMems = memsAfter -+ cpuset := &CpusetGroup{} -+ if err := cpuset.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "cpuset.mems") -+ if err != nil { -+ t.Fatalf("Failed to parse cpuset.mems - %s", err) -+ } -+ -+ if value != memsAfter { -+ t.Fatal("Got the wrong value, set cpuset.mems failed.") -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go -new file mode 100644 -index 0000000000..0ac5b4ed70 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices.go -@@ -0,0 +1,80 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+ "github.com/opencontainers/runc/libcontainer/system" -+) -+ -+type DevicesGroup struct { -+} -+ -+func (s *DevicesGroup) Name() string { -+ return "devices" -+} -+ -+func (s *DevicesGroup) Apply(d *cgroupData) error { -+ _, err := d.join("devices") -+ if err != nil { -+ // We will return error even it's `not found` error, devices -+ // cgroup is hard requirement for container's security. -+ return err -+ } -+ return nil -+} -+ -+func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) error { -+ if system.RunningInUserNS() { -+ return nil -+ } -+ -+ devices := cgroup.Resources.Devices -+ if len(devices) > 0 { -+ for _, dev := range devices { -+ file := "devices.deny" -+ if dev.Allow { -+ file = "devices.allow" -+ } -+ if err := writeFile(path, file, dev.CgroupString()); err != nil { -+ return err -+ } -+ } -+ return nil -+ } -+ if cgroup.Resources.AllowAllDevices != nil { -+ if *cgroup.Resources.AllowAllDevices == false { -+ if err := writeFile(path, "devices.deny", "a"); err != nil { -+ return err -+ } -+ -+ for _, dev := range cgroup.Resources.AllowedDevices { -+ if err := writeFile(path, "devices.allow", dev.CgroupString()); err != nil { -+ return err -+ } -+ } -+ return nil -+ } -+ -+ if err := writeFile(path, "devices.allow", "a"); err != nil { -+ return err -+ } -+ } -+ -+ for _, dev := range cgroup.Resources.DeniedDevices { -+ if err := writeFile(path, "devices.deny", dev.CgroupString()); err != nil { -+ return err -+ } -+ } -+ -+ return nil -+} -+ -+func (s *DevicesGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("devices")) -+} -+ -+func (s *DevicesGroup) GetStats(path string, stats *cgroups.Stats) error { -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices_test.go -new file mode 100644 -index 0000000000..fc635b990f ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/devices_test.go -@@ -0,0 +1,98 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "testing" -+ -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+var ( -+ allowedDevices = []*configs.Device{ -+ { -+ Path: "/dev/zero", -+ Type: 'c', -+ Major: 1, -+ Minor: 5, -+ Permissions: "rwm", -+ FileMode: 0666, -+ }, -+ } -+ allowedList = "c 1:5 rwm" -+ deniedDevices = []*configs.Device{ -+ { -+ Path: "/dev/null", -+ Type: 'c', -+ Major: 1, -+ Minor: 3, -+ Permissions: "rwm", -+ FileMode: 0666, -+ }, -+ } -+ deniedList = "c 1:3 rwm" -+) -+ -+func TestDevicesSetAllow(t *testing.T) { -+ helper := NewCgroupTestUtil("devices", t) -+ defer helper.cleanup() -+ -+ helper.writeFileContents(map[string]string{ -+ "devices.deny": "a", -+ }) -+ allowAllDevices := false -+ helper.CgroupData.config.Resources.AllowAllDevices = &allowAllDevices -+ helper.CgroupData.config.Resources.AllowedDevices = allowedDevices -+ devices := &DevicesGroup{} -+ if err := devices.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "devices.allow") -+ if err != nil { -+ t.Fatalf("Failed to parse devices.allow - %s", err) -+ } -+ -+ if value != allowedList { -+ t.Fatal("Got the wrong value, set devices.allow failed.") -+ } -+ -+ // When AllowAllDevices is nil, devices.allow file should not be modified. -+ helper.CgroupData.config.Resources.AllowAllDevices = nil -+ if err := devices.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ value, err = getCgroupParamString(helper.CgroupPath, "devices.allow") -+ if err != nil { -+ t.Fatalf("Failed to parse devices.allow - %s", err) -+ } -+ if value != allowedList { -+ t.Fatal("devices policy shouldn't have changed on AllowedAllDevices=nil.") -+ } -+} -+ -+func TestDevicesSetDeny(t *testing.T) { -+ helper := NewCgroupTestUtil("devices", t) -+ defer helper.cleanup() -+ -+ helper.writeFileContents(map[string]string{ -+ "devices.allow": "a", -+ }) -+ -+ allowAllDevices := true -+ helper.CgroupData.config.Resources.AllowAllDevices = &allowAllDevices -+ helper.CgroupData.config.Resources.DeniedDevices = deniedDevices -+ devices := &DevicesGroup{} -+ if err := devices.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "devices.deny") -+ if err != nil { -+ t.Fatalf("Failed to parse devices.deny - %s", err) -+ } -+ -+ if value != deniedList { -+ t.Fatal("Got the wrong value, set devices.deny failed.") -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/files.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/files.go -new file mode 100644 -index 0000000000..70e95240c8 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/files.go -@@ -0,0 +1,72 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "fmt" -+ "strconv" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+ "path/filepath" -+) -+ -+type FilesGroup struct { -+} -+ -+func (s *FilesGroup) Name() string { -+ return "files" -+} -+ -+func (s *FilesGroup) Apply(d *cgroupData) error { -+ _, err := d.join("files") -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ return nil -+} -+ -+func (s *FilesGroup) Set(path string, cgroup *configs.Cgroup) error { -+ if cgroup.Resources.FilesLimit != 0 { -+ // "max" is the fallback value. -+ limit := "max" -+ if cgroup.Resources.FilesLimit > 0 { -+ limit = strconv.FormatInt(cgroup.Resources.FilesLimit, 10) -+ } -+ -+ if err := writeFile(path, "files.limit", limit); err != nil { -+ return err -+ } -+ } -+ -+ return nil -+} -+ -+func (s *FilesGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("files")) -+} -+ -+func (s *FilesGroup) GetStats(path string, stats *cgroups.Stats) error { -+ usage, err := getCgroupParamUint(path, "files.usage") -+ if err != nil { -+ return fmt.Errorf("failed to parse files.usage - %s", err) -+ } -+ -+ maxString, err := getCgroupParamString(path, "files.limit") -+ if err != nil { -+ return fmt.Errorf("failed to parse files.limit - %s", err) -+ } -+ -+ // Default if files.limit == "max" is 0 -- which represents "no limit". -+ var max uint64 -+ if maxString != "max" { -+ max, err = parseUint(maxString, 10, 64) -+ if err != nil { -+ return fmt.Errorf("failed to parse files.limit -- unable to parse %q as a uint from Cgroup file %q", maxString, filepath.Join(path, "file.limits")) -+ } -+ } -+ -+ stats.FilesStats.Usage = usage -+ stats.FilesStats.Limit = max -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go -new file mode 100644 -index 0000000000..e70dfe3b95 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer.go -@@ -0,0 +1,61 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "fmt" -+ "strings" -+ "time" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+type FreezerGroup struct { -+} -+ -+func (s *FreezerGroup) Name() string { -+ return "freezer" -+} -+ -+func (s *FreezerGroup) Apply(d *cgroupData) error { -+ _, err := d.join("freezer") -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ return nil -+} -+ -+func (s *FreezerGroup) Set(path string, cgroup *configs.Cgroup) error { -+ switch cgroup.Resources.Freezer { -+ case configs.Frozen, configs.Thawed: -+ if err := writeFile(path, "freezer.state", string(cgroup.Resources.Freezer)); err != nil { -+ return err -+ } -+ -+ for { -+ state, err := readFile(path, "freezer.state") -+ if err != nil { -+ return err -+ } -+ if strings.TrimSpace(state) == string(cgroup.Resources.Freezer) { -+ break -+ } -+ time.Sleep(1 * time.Millisecond) -+ } -+ case configs.Undefined: -+ return nil -+ default: -+ return fmt.Errorf("Invalid argument '%s' to freezer.state", string(cgroup.Resources.Freezer)) -+ } -+ -+ return nil -+} -+ -+func (s *FreezerGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("freezer")) -+} -+ -+func (s *FreezerGroup) GetStats(path string, stats *cgroups.Stats) error { -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer_test.go -new file mode 100644 -index 0000000000..77708db9a6 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/freezer_test.go -@@ -0,0 +1,47 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "testing" -+ -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+func TestFreezerSetState(t *testing.T) { -+ helper := NewCgroupTestUtil("freezer", t) -+ defer helper.cleanup() -+ -+ helper.writeFileContents(map[string]string{ -+ "freezer.state": string(configs.Frozen), -+ }) -+ -+ helper.CgroupData.config.Resources.Freezer = configs.Thawed -+ freezer := &FreezerGroup{} -+ if err := freezer.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "freezer.state") -+ if err != nil { -+ t.Fatalf("Failed to parse freezer.state - %s", err) -+ } -+ if value != string(configs.Thawed) { -+ t.Fatal("Got the wrong value, set freezer.state failed.") -+ } -+} -+ -+func TestFreezerSetInvalidState(t *testing.T) { -+ helper := NewCgroupTestUtil("freezer", t) -+ defer helper.cleanup() -+ -+ const ( -+ invalidArg configs.FreezerState = "Invalid" -+ ) -+ -+ helper.CgroupData.config.Resources.Freezer = invalidArg -+ freezer := &FreezerGroup{} -+ if err := freezer.Set(helper.CgroupPath, helper.CgroupData.config); err == nil { -+ t.Fatal("Failed to return invalid argument error") -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs_unsupported.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs_unsupported.go -new file mode 100644 -index 0000000000..3ef9e03158 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/fs_unsupported.go -@@ -0,0 +1,3 @@ -+// +build !linux -+ -+package fs -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go -new file mode 100644 -index 0000000000..2f9727719d ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb.go -@@ -0,0 +1,71 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "fmt" -+ "strconv" -+ "strings" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+type HugetlbGroup struct { -+} -+ -+func (s *HugetlbGroup) Name() string { -+ return "hugetlb" -+} -+ -+func (s *HugetlbGroup) Apply(d *cgroupData) error { -+ _, err := d.join("hugetlb") -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ return nil -+} -+ -+func (s *HugetlbGroup) Set(path string, cgroup *configs.Cgroup) error { -+ for _, hugetlb := range cgroup.Resources.HugetlbLimit { -+ if err := writeFile(path, strings.Join([]string{"hugetlb", hugetlb.Pagesize, "limit_in_bytes"}, "."), strconv.FormatUint(hugetlb.Limit, 10)); err != nil { -+ return err -+ } -+ } -+ -+ return nil -+} -+ -+func (s *HugetlbGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("hugetlb")) -+} -+ -+func (s *HugetlbGroup) GetStats(path string, stats *cgroups.Stats) error { -+ hugetlbStats := cgroups.HugetlbStats{} -+ for _, pageSize := range HugePageSizes { -+ usage := strings.Join([]string{"hugetlb", pageSize, "usage_in_bytes"}, ".") -+ value, err := getCgroupParamUint(path, usage) -+ if err != nil { -+ return fmt.Errorf("failed to parse %s - %v", usage, err) -+ } -+ hugetlbStats.Usage = value -+ -+ maxUsage := strings.Join([]string{"hugetlb", pageSize, "max_usage_in_bytes"}, ".") -+ value, err = getCgroupParamUint(path, maxUsage) -+ if err != nil { -+ return fmt.Errorf("failed to parse %s - %v", maxUsage, err) -+ } -+ hugetlbStats.MaxUsage = value -+ -+ failcnt := strings.Join([]string{"hugetlb", pageSize, "failcnt"}, ".") -+ value, err = getCgroupParamUint(path, failcnt) -+ if err != nil { -+ return fmt.Errorf("failed to parse %s - %v", failcnt, err) -+ } -+ hugetlbStats.Failcnt = value -+ -+ stats.HugetlbStats[pageSize] = hugetlbStats -+ } -+ -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb_test.go -new file mode 100644 -index 0000000000..2d41c4eb20 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/hugetlb_test.go -@@ -0,0 +1,154 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "fmt" -+ "strconv" -+ "testing" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+const ( -+ hugetlbUsageContents = "128\n" -+ hugetlbMaxUsageContents = "256\n" -+ hugetlbFailcnt = "100\n" -+) -+ -+var ( -+ usage = "hugetlb.%s.usage_in_bytes" -+ limit = "hugetlb.%s.limit_in_bytes" -+ maxUsage = "hugetlb.%s.max_usage_in_bytes" -+ failcnt = "hugetlb.%s.failcnt" -+) -+ -+func TestHugetlbSetHugetlb(t *testing.T) { -+ helper := NewCgroupTestUtil("hugetlb", t) -+ defer helper.cleanup() -+ -+ const ( -+ hugetlbBefore = 256 -+ hugetlbAfter = 512 -+ ) -+ -+ for _, pageSize := range HugePageSizes { -+ helper.writeFileContents(map[string]string{ -+ fmt.Sprintf(limit, pageSize): strconv.Itoa(hugetlbBefore), -+ }) -+ } -+ -+ for _, pageSize := range HugePageSizes { -+ helper.CgroupData.config.Resources.HugetlbLimit = []*configs.HugepageLimit{ -+ { -+ Pagesize: pageSize, -+ Limit: hugetlbAfter, -+ }, -+ } -+ hugetlb := &HugetlbGroup{} -+ if err := hugetlb.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ } -+ -+ for _, pageSize := range HugePageSizes { -+ limit := fmt.Sprintf(limit, pageSize) -+ value, err := getCgroupParamUint(helper.CgroupPath, limit) -+ if err != nil { -+ t.Fatalf("Failed to parse %s - %s", limit, err) -+ } -+ if value != hugetlbAfter { -+ t.Fatalf("Set hugetlb.limit_in_bytes failed. Expected: %v, Got: %v", hugetlbAfter, value) -+ } -+ } -+} -+ -+func TestHugetlbStats(t *testing.T) { -+ helper := NewCgroupTestUtil("hugetlb", t) -+ defer helper.cleanup() -+ for _, pageSize := range HugePageSizes { -+ helper.writeFileContents(map[string]string{ -+ fmt.Sprintf(usage, pageSize): hugetlbUsageContents, -+ fmt.Sprintf(maxUsage, pageSize): hugetlbMaxUsageContents, -+ fmt.Sprintf(failcnt, pageSize): hugetlbFailcnt, -+ }) -+ } -+ -+ hugetlb := &HugetlbGroup{} -+ actualStats := *cgroups.NewStats() -+ err := hugetlb.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatal(err) -+ } -+ expectedStats := cgroups.HugetlbStats{Usage: 128, MaxUsage: 256, Failcnt: 100} -+ for _, pageSize := range HugePageSizes { -+ expectHugetlbStatEquals(t, expectedStats, actualStats.HugetlbStats[pageSize]) -+ } -+} -+ -+func TestHugetlbStatsNoUsageFile(t *testing.T) { -+ helper := NewCgroupTestUtil("hugetlb", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ maxUsage: hugetlbMaxUsageContents, -+ }) -+ -+ hugetlb := &HugetlbGroup{} -+ actualStats := *cgroups.NewStats() -+ err := hugetlb.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected failure") -+ } -+} -+ -+func TestHugetlbStatsNoMaxUsageFile(t *testing.T) { -+ helper := NewCgroupTestUtil("hugetlb", t) -+ defer helper.cleanup() -+ for _, pageSize := range HugePageSizes { -+ helper.writeFileContents(map[string]string{ -+ fmt.Sprintf(usage, pageSize): hugetlbUsageContents, -+ }) -+ } -+ -+ hugetlb := &HugetlbGroup{} -+ actualStats := *cgroups.NewStats() -+ err := hugetlb.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected failure") -+ } -+} -+ -+func TestHugetlbStatsBadUsageFile(t *testing.T) { -+ helper := NewCgroupTestUtil("hugetlb", t) -+ defer helper.cleanup() -+ for _, pageSize := range HugePageSizes { -+ helper.writeFileContents(map[string]string{ -+ fmt.Sprintf(usage, pageSize): "bad", -+ maxUsage: hugetlbMaxUsageContents, -+ }) -+ } -+ -+ hugetlb := &HugetlbGroup{} -+ actualStats := *cgroups.NewStats() -+ err := hugetlb.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected failure") -+ } -+} -+ -+func TestHugetlbStatsBadMaxUsageFile(t *testing.T) { -+ helper := NewCgroupTestUtil("hugetlb", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ usage: hugetlbUsageContents, -+ maxUsage: "bad", -+ }) -+ -+ hugetlb := &HugetlbGroup{} -+ actualStats := *cgroups.NewStats() -+ err := hugetlb.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected failure") -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go -new file mode 100644 -index 0000000000..118cce8f9a ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go -@@ -0,0 +1,301 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "bufio" -+ "fmt" -+ "io/ioutil" -+ "os" -+ "path/filepath" -+ "strconv" -+ "strings" -+ "syscall" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+const ( -+ cgroupKernelMemoryLimit = "memory.kmem.limit_in_bytes" -+ cgroupMemorySwapLimit = "memory.memsw.limit_in_bytes" -+ cgroupMemoryLimit = "memory.limit_in_bytes" -+) -+ -+type MemoryGroup struct { -+} -+ -+func (s *MemoryGroup) Name() string { -+ return "memory" -+} -+ -+func (s *MemoryGroup) Apply(d *cgroupData) (err error) { -+ path, err := d.path("memory") -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } else if path == "" { -+ return nil -+ } -+ if memoryAssigned(d.config) { -+ if _, err := os.Stat(path); os.IsNotExist(err) { -+ if err := os.MkdirAll(path, 0755); err != nil { -+ return err -+ } -+ } -+ if d.config.KernelMemory != 0 { -+ if err := EnableKernelMemoryAccounting(path); err != nil { -+ return err -+ } -+ } -+ } -+ defer func() { -+ if err != nil { -+ os.RemoveAll(path) -+ } -+ }() -+ -+ // We need to join memory cgroup after set memory limits, because -+ // kmem.limit_in_bytes can only be set when the cgroup is empty. -+ _, err = d.join("memory") -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ return nil -+} -+ -+func EnableKernelMemoryAccounting(path string) error { -+ // Check if kernel memory is enabled -+ // We have to limit the kernel memory here as it won't be accounted at all -+ // until a limit is set on the cgroup and limit cannot be set once the -+ // cgroup has children, or if there are already tasks in the cgroup. -+ for _, i := range []int64{1, -1} { -+ if err := setKernelMemory(path, i); err != nil { -+ return err -+ } -+ } -+ return nil -+} -+ -+func setKernelMemory(path string, kernelMemoryLimit int64) error { -+ if path == "" { -+ return fmt.Errorf("no such directory for %s", cgroupKernelMemoryLimit) -+ } -+ if !cgroups.PathExists(filepath.Join(path, cgroupKernelMemoryLimit)) { -+ // kernel memory is not enabled on the system so we should do nothing -+ return nil -+ } -+ if err := ioutil.WriteFile(filepath.Join(path, cgroupKernelMemoryLimit), []byte(strconv.FormatInt(kernelMemoryLimit, 10)), 0700); err != nil { -+ // Check if the error number returned by the syscall is "EBUSY" -+ // The EBUSY signal is returned on attempts to write to the -+ // memory.kmem.limit_in_bytes file if the cgroup has children or -+ // once tasks have been attached to the cgroup -+ if pathErr, ok := err.(*os.PathError); ok { -+ if errNo, ok := pathErr.Err.(syscall.Errno); ok { -+ if errNo == syscall.EBUSY { -+ return fmt.Errorf("failed to set %s, because either tasks have already joined this cgroup or it has children", cgroupKernelMemoryLimit) -+ } -+ } -+ } -+ return fmt.Errorf("failed to write %v to %v: %v", kernelMemoryLimit, cgroupKernelMemoryLimit, err) -+ } -+ return nil -+} -+ -+func setMemoryAndSwap(path string, cgroup *configs.Cgroup) error { -+ // If the memory update is set to -1 we should also -+ // set swap to -1, it means unlimited memory. -+ if cgroup.Resources.Memory == -1 { -+ // Only set swap if it's enabled in kernel -+ if cgroups.PathExists(filepath.Join(path, cgroupMemorySwapLimit)) { -+ cgroup.Resources.MemorySwap = -1 -+ } -+ } -+ -+ // When memory and swap memory are both set, we need to handle the cases -+ // for updating container. -+ if cgroup.Resources.Memory != 0 && cgroup.Resources.MemorySwap != 0 { -+ memoryUsage, err := getMemoryData(path, "") -+ if err != nil { -+ return err -+ } -+ -+ // When update memory limit, we should adapt the write sequence -+ // for memory and swap memory, so it won't fail because the new -+ // value and the old value don't fit kernel's validation. -+ if cgroup.Resources.MemorySwap == -1 || memoryUsage.Limit < uint64(cgroup.Resources.MemorySwap) { -+ if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatInt(cgroup.Resources.MemorySwap, 10)); err != nil { -+ return err -+ } -+ if err := writeFile(path, cgroupMemoryLimit, strconv.FormatInt(cgroup.Resources.Memory, 10)); err != nil { -+ return err -+ } -+ } else { -+ if err := writeFile(path, cgroupMemoryLimit, strconv.FormatInt(cgroup.Resources.Memory, 10)); err != nil { -+ return err -+ } -+ if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatInt(cgroup.Resources.MemorySwap, 10)); err != nil { -+ return err -+ } -+ } -+ } else { -+ if cgroup.Resources.Memory != 0 { -+ if err := writeFile(path, cgroupMemoryLimit, strconv.FormatInt(cgroup.Resources.Memory, 10)); err != nil { -+ return err -+ } -+ } -+ if cgroup.Resources.MemorySwap != 0 { -+ if err := writeFile(path, cgroupMemorySwapLimit, strconv.FormatInt(cgroup.Resources.MemorySwap, 10)); err != nil { -+ return err -+ } -+ } -+ } -+ -+ return nil -+} -+ -+func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error { -+ if err := setMemoryAndSwap(path, cgroup); err != nil { -+ return err -+ } -+ -+ if cgroup.Resources.KernelMemory != 0 { -+ if err := setKernelMemory(path, cgroup.Resources.KernelMemory); err != nil { -+ return err -+ } -+ } -+ -+ if cgroup.Resources.MemoryReservation != 0 { -+ if err := writeFile(path, "memory.soft_limit_in_bytes", strconv.FormatInt(cgroup.Resources.MemoryReservation, 10)); err != nil { -+ return err -+ } -+ } -+ -+ if cgroup.Resources.KernelMemoryTCP != 0 { -+ if err := writeFile(path, "memory.kmem.tcp.limit_in_bytes", strconv.FormatInt(cgroup.Resources.KernelMemoryTCP, 10)); err != nil { -+ return err -+ } -+ } -+ if cgroup.Resources.OomKillDisable { -+ if err := writeFile(path, "memory.oom_control", "1"); err != nil { -+ return err -+ } -+ } -+ if cgroup.Resources.MemorySwappiness == nil || int64(*cgroup.Resources.MemorySwappiness) == -1 { -+ return nil -+ } else if *cgroup.Resources.MemorySwappiness <= 100 { -+ if err := writeFile(path, "memory.swappiness", strconv.FormatUint(*cgroup.Resources.MemorySwappiness, 10)); err != nil { -+ return err -+ } -+ } else { -+ return fmt.Errorf("invalid value:%d. valid memory swappiness range is 0-100", *cgroup.Resources.MemorySwappiness) -+ } -+ -+ return nil -+} -+ -+func (s *MemoryGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("memory")) -+} -+ -+func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error { -+ // Set stats from memory.stat. -+ statsFile, err := os.Open(filepath.Join(path, "memory.stat")) -+ if err != nil { -+ if os.IsNotExist(err) { -+ return nil -+ } -+ return err -+ } -+ defer statsFile.Close() -+ -+ sc := bufio.NewScanner(statsFile) -+ for sc.Scan() { -+ t, v, err := getCgroupParamKeyValue(sc.Text()) -+ if err != nil { -+ return fmt.Errorf("failed to parse memory.stat (%q) - %v", sc.Text(), err) -+ } -+ stats.MemoryStats.Stats[t] = v -+ } -+ stats.MemoryStats.Cache = stats.MemoryStats.Stats["cache"] -+ -+ memoryUsage, err := getMemoryData(path, "") -+ if err != nil { -+ return err -+ } -+ stats.MemoryStats.Usage = memoryUsage -+ swapUsage, err := getMemoryData(path, "memsw") -+ if err != nil { -+ return err -+ } -+ stats.MemoryStats.SwapUsage = swapUsage -+ kernelUsage, err := getMemoryData(path, "kmem") -+ if err != nil { -+ return err -+ } -+ stats.MemoryStats.KernelUsage = kernelUsage -+ kernelTCPUsage, err := getMemoryData(path, "kmem.tcp") -+ if err != nil { -+ return err -+ } -+ stats.MemoryStats.KernelTCPUsage = kernelTCPUsage -+ -+ return nil -+} -+ -+func memoryAssigned(cgroup *configs.Cgroup) bool { -+ return cgroup.Resources.Memory != 0 || -+ cgroup.Resources.MemoryReservation != 0 || -+ cgroup.Resources.MemorySwap > 0 || -+ cgroup.Resources.KernelMemory > 0 || -+ cgroup.Resources.KernelMemoryTCP > 0 || -+ cgroup.Resources.OomKillDisable || -+ (cgroup.Resources.MemorySwappiness != nil && int64(*cgroup.Resources.MemorySwappiness) != -1) -+} -+ -+func getMemoryData(path, name string) (cgroups.MemoryData, error) { -+ memoryData := cgroups.MemoryData{} -+ -+ moduleName := "memory" -+ if name != "" { -+ moduleName = strings.Join([]string{"memory", name}, ".") -+ } -+ usage := strings.Join([]string{moduleName, "usage_in_bytes"}, ".") -+ maxUsage := strings.Join([]string{moduleName, "max_usage_in_bytes"}, ".") -+ failcnt := strings.Join([]string{moduleName, "failcnt"}, ".") -+ limit := strings.Join([]string{moduleName, "limit_in_bytes"}, ".") -+ -+ value, err := getCgroupParamUint(path, usage) -+ if err != nil { -+ if moduleName != "memory" && os.IsNotExist(err) { -+ return cgroups.MemoryData{}, nil -+ } -+ return cgroups.MemoryData{}, fmt.Errorf("failed to parse %s - %v", usage, err) -+ } -+ memoryData.Usage = value -+ value, err = getCgroupParamUint(path, maxUsage) -+ if err != nil { -+ if moduleName != "memory" && os.IsNotExist(err) { -+ return cgroups.MemoryData{}, nil -+ } -+ return cgroups.MemoryData{}, fmt.Errorf("failed to parse %s - %v", maxUsage, err) -+ } -+ memoryData.MaxUsage = value -+ value, err = getCgroupParamUint(path, failcnt) -+ if err != nil { -+ if moduleName != "memory" && os.IsNotExist(err) { -+ return cgroups.MemoryData{}, nil -+ } -+ return cgroups.MemoryData{}, fmt.Errorf("failed to parse %s - %v", failcnt, err) -+ } -+ memoryData.Failcnt = value -+ value, err = getCgroupParamUint(path, limit) -+ if err != nil { -+ if moduleName != "memory" && os.IsNotExist(err) { -+ return cgroups.MemoryData{}, nil -+ } -+ return cgroups.MemoryData{}, fmt.Errorf("failed to parse %s - %v", limit, err) -+ } -+ memoryData.Limit = value -+ -+ return memoryData, nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory_test.go -new file mode 100644 -index 0000000000..4b656dc628 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/memory_test.go -@@ -0,0 +1,453 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "strconv" -+ "testing" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+) -+ -+const ( -+ memoryStatContents = `cache 512 -+rss 1024` -+ memoryUsageContents = "2048\n" -+ memoryMaxUsageContents = "4096\n" -+ memoryFailcnt = "100\n" -+ memoryLimitContents = "8192\n" -+) -+ -+func TestMemorySetMemory(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ -+ const ( -+ memoryBefore = 314572800 // 300M -+ memoryAfter = 524288000 // 500M -+ reservationBefore = 209715200 // 200M -+ reservationAfter = 314572800 // 300M -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "memory.limit_in_bytes": strconv.Itoa(memoryBefore), -+ "memory.soft_limit_in_bytes": strconv.Itoa(reservationBefore), -+ }) -+ -+ helper.CgroupData.config.Resources.Memory = memoryAfter -+ helper.CgroupData.config.Resources.MemoryReservation = reservationAfter -+ memory := &MemoryGroup{} -+ if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamUint(helper.CgroupPath, "memory.limit_in_bytes") -+ if err != nil { -+ t.Fatalf("Failed to parse memory.limit_in_bytes - %s", err) -+ } -+ if value != memoryAfter { -+ t.Fatal("Got the wrong value, set memory.limit_in_bytes failed.") -+ } -+ -+ value, err = getCgroupParamUint(helper.CgroupPath, "memory.soft_limit_in_bytes") -+ if err != nil { -+ t.Fatalf("Failed to parse memory.soft_limit_in_bytes - %s", err) -+ } -+ if value != reservationAfter { -+ t.Fatal("Got the wrong value, set memory.soft_limit_in_bytes failed.") -+ } -+} -+ -+func TestMemorySetMemoryswap(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ -+ const ( -+ memoryswapBefore = 314572800 // 300M -+ memoryswapAfter = 524288000 // 500M -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore), -+ }) -+ -+ helper.CgroupData.config.Resources.MemorySwap = memoryswapAfter -+ memory := &MemoryGroup{} -+ if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes") -+ if err != nil { -+ t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err) -+ } -+ if value != memoryswapAfter { -+ t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.") -+ } -+} -+ -+func TestMemorySetMemoryLargerThanSwap(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ -+ const ( -+ memoryBefore = 314572800 // 300M -+ memoryswapBefore = 524288000 // 500M -+ memoryAfter = 629145600 // 600M -+ memoryswapAfter = 838860800 // 800M -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "memory.limit_in_bytes": strconv.Itoa(memoryBefore), -+ "memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore), -+ // Set will call getMemoryData when memory and swap memory are -+ // both set, fake these fields so we don't get error. -+ "memory.usage_in_bytes": "0", -+ "memory.max_usage_in_bytes": "0", -+ "memory.failcnt": "0", -+ }) -+ -+ helper.CgroupData.config.Resources.Memory = memoryAfter -+ helper.CgroupData.config.Resources.MemorySwap = memoryswapAfter -+ memory := &MemoryGroup{} -+ if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamUint(helper.CgroupPath, "memory.limit_in_bytes") -+ if err != nil { -+ t.Fatalf("Failed to parse memory.limit_in_bytes - %s", err) -+ } -+ if value != memoryAfter { -+ t.Fatal("Got the wrong value, set memory.limit_in_bytes failed.") -+ } -+ value, err = getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes") -+ if err != nil { -+ t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err) -+ } -+ if value != memoryswapAfter { -+ t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.") -+ } -+} -+ -+func TestMemorySetSwapSmallerThanMemory(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ -+ const ( -+ memoryBefore = 629145600 // 600M -+ memoryswapBefore = 838860800 // 800M -+ memoryAfter = 314572800 // 300M -+ memoryswapAfter = 524288000 // 500M -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "memory.limit_in_bytes": strconv.Itoa(memoryBefore), -+ "memory.memsw.limit_in_bytes": strconv.Itoa(memoryswapBefore), -+ // Set will call getMemoryData when memory and swap memory are -+ // both set, fake these fields so we don't get error. -+ "memory.usage_in_bytes": "0", -+ "memory.max_usage_in_bytes": "0", -+ "memory.failcnt": "0", -+ }) -+ -+ helper.CgroupData.config.Resources.Memory = memoryAfter -+ helper.CgroupData.config.Resources.MemorySwap = memoryswapAfter -+ memory := &MemoryGroup{} -+ if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamUint(helper.CgroupPath, "memory.limit_in_bytes") -+ if err != nil { -+ t.Fatalf("Failed to parse memory.limit_in_bytes - %s", err) -+ } -+ if value != memoryAfter { -+ t.Fatal("Got the wrong value, set memory.limit_in_bytes failed.") -+ } -+ value, err = getCgroupParamUint(helper.CgroupPath, "memory.memsw.limit_in_bytes") -+ if err != nil { -+ t.Fatalf("Failed to parse memory.memsw.limit_in_bytes - %s", err) -+ } -+ if value != memoryswapAfter { -+ t.Fatal("Got the wrong value, set memory.memsw.limit_in_bytes failed.") -+ } -+} -+ -+func TestMemorySetKernelMemory(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ -+ const ( -+ kernelMemoryBefore = 314572800 // 300M -+ kernelMemoryAfter = 524288000 // 500M -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "memory.kmem.limit_in_bytes": strconv.Itoa(kernelMemoryBefore), -+ }) -+ -+ helper.CgroupData.config.Resources.KernelMemory = kernelMemoryAfter -+ memory := &MemoryGroup{} -+ if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamUint(helper.CgroupPath, "memory.kmem.limit_in_bytes") -+ if err != nil { -+ t.Fatalf("Failed to parse memory.kmem.limit_in_bytes - %s", err) -+ } -+ if value != kernelMemoryAfter { -+ t.Fatal("Got the wrong value, set memory.kmem.limit_in_bytes failed.") -+ } -+} -+ -+func TestMemorySetKernelMemoryTCP(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ -+ const ( -+ kernelMemoryTCPBefore = 314572800 // 300M -+ kernelMemoryTCPAfter = 524288000 // 500M -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "memory.kmem.tcp.limit_in_bytes": strconv.Itoa(kernelMemoryTCPBefore), -+ }) -+ -+ helper.CgroupData.config.Resources.KernelMemoryTCP = kernelMemoryTCPAfter -+ memory := &MemoryGroup{} -+ if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamUint(helper.CgroupPath, "memory.kmem.tcp.limit_in_bytes") -+ if err != nil { -+ t.Fatalf("Failed to parse memory.kmem.tcp.limit_in_bytes - %s", err) -+ } -+ if value != kernelMemoryTCPAfter { -+ t.Fatal("Got the wrong value, set memory.kmem.tcp.limit_in_bytes failed.") -+ } -+} -+ -+func TestMemorySetMemorySwappinessDefault(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ -+ swappinessBefore := 60 // default is 60 -+ swappinessAfter := uint64(0) -+ -+ helper.writeFileContents(map[string]string{ -+ "memory.swappiness": strconv.Itoa(swappinessBefore), -+ }) -+ -+ helper.CgroupData.config.Resources.MemorySwappiness = &swappinessAfter -+ memory := &MemoryGroup{} -+ if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamUint(helper.CgroupPath, "memory.swappiness") -+ if err != nil { -+ t.Fatalf("Failed to parse memory.swappiness - %s", err) -+ } -+ if value != swappinessAfter { -+ t.Fatalf("Got the wrong value (%d), set memory.swappiness = %d failed.", value, swappinessAfter) -+ } -+} -+ -+func TestMemoryStats(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "memory.stat": memoryStatContents, -+ "memory.usage_in_bytes": memoryUsageContents, -+ "memory.limit_in_bytes": memoryLimitContents, -+ "memory.max_usage_in_bytes": memoryMaxUsageContents, -+ "memory.failcnt": memoryFailcnt, -+ "memory.memsw.usage_in_bytes": memoryUsageContents, -+ "memory.memsw.max_usage_in_bytes": memoryMaxUsageContents, -+ "memory.memsw.failcnt": memoryFailcnt, -+ "memory.memsw.limit_in_bytes": memoryLimitContents, -+ "memory.kmem.usage_in_bytes": memoryUsageContents, -+ "memory.kmem.max_usage_in_bytes": memoryMaxUsageContents, -+ "memory.kmem.failcnt": memoryFailcnt, -+ "memory.kmem.limit_in_bytes": memoryLimitContents, -+ }) -+ -+ memory := &MemoryGroup{} -+ actualStats := *cgroups.NewStats() -+ err := memory.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatal(err) -+ } -+ expectedStats := cgroups.MemoryStats{Cache: 512, Usage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, SwapUsage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, KernelUsage: cgroups.MemoryData{Usage: 2048, MaxUsage: 4096, Failcnt: 100, Limit: 8192}, Stats: map[string]uint64{"cache": 512, "rss": 1024}} -+ expectMemoryStatEquals(t, expectedStats, actualStats.MemoryStats) -+} -+ -+func TestMemoryStatsNoStatFile(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "memory.usage_in_bytes": memoryUsageContents, -+ "memory.max_usage_in_bytes": memoryMaxUsageContents, -+ "memory.limit_in_bytes": memoryLimitContents, -+ }) -+ -+ memory := &MemoryGroup{} -+ actualStats := *cgroups.NewStats() -+ err := memory.GetStats(helper.CgroupPath, &actualStats) -+ if err != nil { -+ t.Fatal(err) -+ } -+} -+ -+func TestMemoryStatsNoUsageFile(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "memory.stat": memoryStatContents, -+ "memory.max_usage_in_bytes": memoryMaxUsageContents, -+ "memory.limit_in_bytes": memoryLimitContents, -+ }) -+ -+ memory := &MemoryGroup{} -+ actualStats := *cgroups.NewStats() -+ err := memory.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected failure") -+ } -+} -+ -+func TestMemoryStatsNoMaxUsageFile(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "memory.stat": memoryStatContents, -+ "memory.usage_in_bytes": memoryUsageContents, -+ "memory.limit_in_bytes": memoryLimitContents, -+ }) -+ -+ memory := &MemoryGroup{} -+ actualStats := *cgroups.NewStats() -+ err := memory.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected failure") -+ } -+} -+ -+func TestMemoryStatsNoLimitInBytesFile(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "memory.stat": memoryStatContents, -+ "memory.usage_in_bytes": memoryUsageContents, -+ "memory.max_usage_in_bytes": memoryMaxUsageContents, -+ }) -+ -+ memory := &MemoryGroup{} -+ actualStats := *cgroups.NewStats() -+ err := memory.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected failure") -+ } -+} -+ -+func TestMemoryStatsBadStatFile(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "memory.stat": "rss rss", -+ "memory.usage_in_bytes": memoryUsageContents, -+ "memory.max_usage_in_bytes": memoryMaxUsageContents, -+ "memory.limit_in_bytes": memoryLimitContents, -+ }) -+ -+ memory := &MemoryGroup{} -+ actualStats := *cgroups.NewStats() -+ err := memory.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected failure") -+ } -+} -+ -+func TestMemoryStatsBadUsageFile(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "memory.stat": memoryStatContents, -+ "memory.usage_in_bytes": "bad", -+ "memory.max_usage_in_bytes": memoryMaxUsageContents, -+ "memory.limit_in_bytes": memoryLimitContents, -+ }) -+ -+ memory := &MemoryGroup{} -+ actualStats := *cgroups.NewStats() -+ err := memory.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected failure") -+ } -+} -+ -+func TestMemoryStatsBadMaxUsageFile(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "memory.stat": memoryStatContents, -+ "memory.usage_in_bytes": memoryUsageContents, -+ "memory.max_usage_in_bytes": "bad", -+ "memory.limit_in_bytes": memoryLimitContents, -+ }) -+ -+ memory := &MemoryGroup{} -+ actualStats := *cgroups.NewStats() -+ err := memory.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected failure") -+ } -+} -+ -+func TestMemoryStatsBadLimitInBytesFile(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ helper.writeFileContents(map[string]string{ -+ "memory.stat": memoryStatContents, -+ "memory.usage_in_bytes": memoryUsageContents, -+ "memory.max_usage_in_bytes": memoryMaxUsageContents, -+ "memory.limit_in_bytes": "bad", -+ }) -+ -+ memory := &MemoryGroup{} -+ actualStats := *cgroups.NewStats() -+ err := memory.GetStats(helper.CgroupPath, &actualStats) -+ if err == nil { -+ t.Fatal("Expected failure") -+ } -+} -+ -+func TestMemorySetOomControl(t *testing.T) { -+ helper := NewCgroupTestUtil("memory", t) -+ defer helper.cleanup() -+ -+ const ( -+ oomKillDisable = 1 // disable oom killer, default is 0 -+ ) -+ -+ helper.writeFileContents(map[string]string{ -+ "memory.oom_control": strconv.Itoa(oomKillDisable), -+ }) -+ -+ memory := &MemoryGroup{} -+ if err := memory.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamUint(helper.CgroupPath, "memory.oom_control") -+ if err != nil { -+ t.Fatalf("Failed to parse memory.oom_control - %s", err) -+ } -+ -+ if value != oomKillDisable { -+ t.Fatalf("Got the wrong value, set memory.oom_control failed.") -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go -new file mode 100644 -index 0000000000..d8cf1d87c0 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/name.go -@@ -0,0 +1,40 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+type NameGroup struct { -+ GroupName string -+ Join bool -+} -+ -+func (s *NameGroup) Name() string { -+ return s.GroupName -+} -+ -+func (s *NameGroup) Apply(d *cgroupData) error { -+ if s.Join { -+ // ignore errors if the named cgroup does not exist -+ d.join(s.GroupName) -+ } -+ return nil -+} -+ -+func (s *NameGroup) Set(path string, cgroup *configs.Cgroup) error { -+ return nil -+} -+ -+func (s *NameGroup) Remove(d *cgroupData) error { -+ if s.Join { -+ removePath(d.path(s.GroupName)) -+ } -+ return nil -+} -+ -+func (s *NameGroup) GetStats(path string, stats *cgroups.Stats) error { -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go -new file mode 100644 -index 0000000000..8e74b645ea ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls.go -@@ -0,0 +1,43 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "strconv" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+type NetClsGroup struct { -+} -+ -+func (s *NetClsGroup) Name() string { -+ return "net_cls" -+} -+ -+func (s *NetClsGroup) Apply(d *cgroupData) error { -+ _, err := d.join("net_cls") -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ return nil -+} -+ -+func (s *NetClsGroup) Set(path string, cgroup *configs.Cgroup) error { -+ if cgroup.Resources.NetClsClassid != 0 { -+ if err := writeFile(path, "net_cls.classid", strconv.FormatUint(uint64(cgroup.Resources.NetClsClassid), 10)); err != nil { -+ return err -+ } -+ } -+ -+ return nil -+} -+ -+func (s *NetClsGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("net_cls")) -+} -+ -+func (s *NetClsGroup) GetStats(path string, stats *cgroups.Stats) error { -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls_test.go -new file mode 100644 -index 0000000000..c00e8a8d6f ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_cls_test.go -@@ -0,0 +1,39 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "strconv" -+ "testing" -+) -+ -+const ( -+ classidBefore = 0x100002 -+ classidAfter = 0x100001 -+) -+ -+func TestNetClsSetClassid(t *testing.T) { -+ helper := NewCgroupTestUtil("net_cls", t) -+ defer helper.cleanup() -+ -+ helper.writeFileContents(map[string]string{ -+ "net_cls.classid": strconv.FormatUint(classidBefore, 10), -+ }) -+ -+ helper.CgroupData.config.Resources.NetClsClassid = classidAfter -+ netcls := &NetClsGroup{} -+ if err := netcls.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ // As we are in mock environment, we can't get correct value of classid from -+ // net_cls.classid. -+ // So. we just judge if we successfully write classid into file -+ value, err := getCgroupParamUint(helper.CgroupPath, "net_cls.classid") -+ if err != nil { -+ t.Fatalf("Failed to parse net_cls.classid - %s", err) -+ } -+ if value != classidAfter { -+ t.Fatal("Got the wrong value, set net_cls.classid failed.") -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio.go -new file mode 100644 -index 0000000000..d0ab2af894 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio.go -@@ -0,0 +1,41 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+type NetPrioGroup struct { -+} -+ -+func (s *NetPrioGroup) Name() string { -+ return "net_prio" -+} -+ -+func (s *NetPrioGroup) Apply(d *cgroupData) error { -+ _, err := d.join("net_prio") -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ return nil -+} -+ -+func (s *NetPrioGroup) Set(path string, cgroup *configs.Cgroup) error { -+ for _, prioMap := range cgroup.Resources.NetPrioIfpriomap { -+ if err := writeFile(path, "net_prio.ifpriomap", prioMap.CgroupString()); err != nil { -+ return err -+ } -+ } -+ -+ return nil -+} -+ -+func (s *NetPrioGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("net_prio")) -+} -+ -+func (s *NetPrioGroup) GetStats(path string, stats *cgroups.Stats) error { -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio_test.go -new file mode 100644 -index 0000000000..efbf0639a0 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/net_prio_test.go -@@ -0,0 +1,38 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "strings" -+ "testing" -+ -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+var ( -+ prioMap = []*configs.IfPrioMap{ -+ { -+ Interface: "test", -+ Priority: 5, -+ }, -+ } -+) -+ -+func TestNetPrioSetIfPrio(t *testing.T) { -+ helper := NewCgroupTestUtil("net_prio", t) -+ defer helper.cleanup() -+ -+ helper.CgroupData.config.Resources.NetPrioIfpriomap = prioMap -+ netPrio := &NetPrioGroup{} -+ if err := netPrio.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "net_prio.ifpriomap") -+ if err != nil { -+ t.Fatalf("Failed to parse net_prio.ifpriomap - %s", err) -+ } -+ if !strings.Contains(value, "test 5") { -+ t.Fatal("Got the wrong value, set net_prio.ifpriomap failed.") -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/perf_event.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/perf_event.go -new file mode 100644 -index 0000000000..5693676d3a ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/perf_event.go -@@ -0,0 +1,35 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+type PerfEventGroup struct { -+} -+ -+func (s *PerfEventGroup) Name() string { -+ return "perf_event" -+} -+ -+func (s *PerfEventGroup) Apply(d *cgroupData) error { -+ // we just want to join this group even though we don't set anything -+ if _, err := d.join("perf_event"); err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ return nil -+} -+ -+func (s *PerfEventGroup) Set(path string, cgroup *configs.Cgroup) error { -+ return nil -+} -+ -+func (s *PerfEventGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("perf_event")) -+} -+ -+func (s *PerfEventGroup) GetStats(path string, stats *cgroups.Stats) error { -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids.go -new file mode 100644 -index 0000000000..f1e3720551 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids.go -@@ -0,0 +1,73 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "fmt" -+ "path/filepath" -+ "strconv" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+type PidsGroup struct { -+} -+ -+func (s *PidsGroup) Name() string { -+ return "pids" -+} -+ -+func (s *PidsGroup) Apply(d *cgroupData) error { -+ _, err := d.join("pids") -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ return nil -+} -+ -+func (s *PidsGroup) Set(path string, cgroup *configs.Cgroup) error { -+ if cgroup.Resources.PidsLimit != 0 { -+ // "max" is the fallback value. -+ limit := "max" -+ -+ if cgroup.Resources.PidsLimit > 0 { -+ limit = strconv.FormatInt(cgroup.Resources.PidsLimit, 10) -+ } -+ -+ if err := writeFile(path, "pids.max", limit); err != nil { -+ return err -+ } -+ } -+ -+ return nil -+} -+ -+func (s *PidsGroup) Remove(d *cgroupData) error { -+ return removePath(d.path("pids")) -+} -+ -+func (s *PidsGroup) GetStats(path string, stats *cgroups.Stats) error { -+ current, err := getCgroupParamUint(path, "pids.current") -+ if err != nil { -+ return fmt.Errorf("failed to parse pids.current - %s", err) -+ } -+ -+ maxString, err := getCgroupParamString(path, "pids.max") -+ if err != nil { -+ return fmt.Errorf("failed to parse pids.max - %s", err) -+ } -+ -+ // Default if pids.max == "max" is 0 -- which represents "no limit". -+ var max uint64 -+ if maxString != "max" { -+ max, err = parseUint(maxString, 10, 64) -+ if err != nil { -+ return fmt.Errorf("failed to parse pids.max - unable to parse %q as a uint from Cgroup file %q", maxString, filepath.Join(path, "pids.max")) -+ } -+ } -+ -+ stats.PidsStats.Current = current -+ stats.PidsStats.Limit = max -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids_test.go -new file mode 100644 -index 0000000000..10671247ba ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/pids_test.go -@@ -0,0 +1,111 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "strconv" -+ "testing" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+) -+ -+const ( -+ maxUnlimited = -1 -+ maxLimited = 1024 -+) -+ -+func TestPidsSetMax(t *testing.T) { -+ helper := NewCgroupTestUtil("pids", t) -+ defer helper.cleanup() -+ -+ helper.writeFileContents(map[string]string{ -+ "pids.max": "max", -+ }) -+ -+ helper.CgroupData.config.Resources.PidsLimit = maxLimited -+ pids := &PidsGroup{} -+ if err := pids.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamUint(helper.CgroupPath, "pids.max") -+ if err != nil { -+ t.Fatalf("Failed to parse pids.max - %s", err) -+ } -+ -+ if value != maxLimited { -+ t.Fatalf("Expected %d, got %d for setting pids.max - limited", maxLimited, value) -+ } -+} -+ -+func TestPidsSetUnlimited(t *testing.T) { -+ helper := NewCgroupTestUtil("pids", t) -+ defer helper.cleanup() -+ -+ helper.writeFileContents(map[string]string{ -+ "pids.max": strconv.Itoa(maxLimited), -+ }) -+ -+ helper.CgroupData.config.Resources.PidsLimit = maxUnlimited -+ pids := &PidsGroup{} -+ if err := pids.Set(helper.CgroupPath, helper.CgroupData.config); err != nil { -+ t.Fatal(err) -+ } -+ -+ value, err := getCgroupParamString(helper.CgroupPath, "pids.max") -+ if err != nil { -+ t.Fatalf("Failed to parse pids.max - %s", err) -+ } -+ -+ if value != "max" { -+ t.Fatalf("Expected %s, got %s for setting pids.max - unlimited", "max", value) -+ } -+} -+ -+func TestPidsStats(t *testing.T) { -+ helper := NewCgroupTestUtil("pids", t) -+ defer helper.cleanup() -+ -+ helper.writeFileContents(map[string]string{ -+ "pids.current": strconv.Itoa(1337), -+ "pids.max": strconv.Itoa(maxLimited), -+ }) -+ -+ pids := &PidsGroup{} -+ stats := *cgroups.NewStats() -+ if err := pids.GetStats(helper.CgroupPath, &stats); err != nil { -+ t.Fatal(err) -+ } -+ -+ if stats.PidsStats.Current != 1337 { -+ t.Fatalf("Expected %d, got %d for pids.current", 1337, stats.PidsStats.Current) -+ } -+ -+ if stats.PidsStats.Limit != maxLimited { -+ t.Fatalf("Expected %d, got %d for pids.max", maxLimited, stats.PidsStats.Limit) -+ } -+} -+ -+func TestPidsStatsUnlimited(t *testing.T) { -+ helper := NewCgroupTestUtil("pids", t) -+ defer helper.cleanup() -+ -+ helper.writeFileContents(map[string]string{ -+ "pids.current": strconv.Itoa(4096), -+ "pids.max": "max", -+ }) -+ -+ pids := &PidsGroup{} -+ stats := *cgroups.NewStats() -+ if err := pids.GetStats(helper.CgroupPath, &stats); err != nil { -+ t.Fatal(err) -+ } -+ -+ if stats.PidsStats.Current != 4096 { -+ t.Fatalf("Expected %d, got %d for pids.current", 4096, stats.PidsStats.Current) -+ } -+ -+ if stats.PidsStats.Limit != 0 { -+ t.Fatalf("Expected %d, got %d for pids.max", 0, stats.PidsStats.Limit) -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/stats_util_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/stats_util_test.go -new file mode 100644 -index 0000000000..d0ab047418 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/stats_util_test.go -@@ -0,0 +1,117 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "fmt" -+ "testing" -+ -+ "github.com/sirupsen/logrus" -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+) -+ -+func blkioStatEntryEquals(expected, actual []cgroups.BlkioStatEntry) error { -+ if len(expected) != len(actual) { -+ return fmt.Errorf("blkioStatEntries length do not match") -+ } -+ for i, expValue := range expected { -+ actValue := actual[i] -+ if expValue != actValue { -+ return fmt.Errorf("Expected blkio stat entry %v but found %v", expValue, actValue) -+ } -+ } -+ return nil -+} -+ -+func expectBlkioStatsEquals(t *testing.T, expected, actual cgroups.BlkioStats) { -+ if err := blkioStatEntryEquals(expected.IoServiceBytesRecursive, actual.IoServiceBytesRecursive); err != nil { -+ logrus.Printf("blkio IoServiceBytesRecursive do not match - %s\n", err) -+ t.Fail() -+ } -+ -+ if err := blkioStatEntryEquals(expected.IoServicedRecursive, actual.IoServicedRecursive); err != nil { -+ logrus.Printf("blkio IoServicedRecursive do not match - %s\n", err) -+ t.Fail() -+ } -+ -+ if err := blkioStatEntryEquals(expected.IoQueuedRecursive, actual.IoQueuedRecursive); err != nil { -+ logrus.Printf("blkio IoQueuedRecursive do not match - %s\n", err) -+ t.Fail() -+ } -+ -+ if err := blkioStatEntryEquals(expected.SectorsRecursive, actual.SectorsRecursive); err != nil { -+ logrus.Printf("blkio SectorsRecursive do not match - %s\n", err) -+ t.Fail() -+ } -+ -+ if err := blkioStatEntryEquals(expected.IoServiceTimeRecursive, actual.IoServiceTimeRecursive); err != nil { -+ logrus.Printf("blkio IoServiceTimeRecursive do not match - %s\n", err) -+ t.Fail() -+ } -+ -+ if err := blkioStatEntryEquals(expected.IoWaitTimeRecursive, actual.IoWaitTimeRecursive); err != nil { -+ logrus.Printf("blkio IoWaitTimeRecursive do not match - %s\n", err) -+ t.Fail() -+ } -+ -+ if err := blkioStatEntryEquals(expected.IoMergedRecursive, actual.IoMergedRecursive); err != nil { -+ logrus.Printf("blkio IoMergedRecursive do not match - %v vs %v\n", expected.IoMergedRecursive, actual.IoMergedRecursive) -+ t.Fail() -+ } -+ -+ if err := blkioStatEntryEquals(expected.IoTimeRecursive, actual.IoTimeRecursive); err != nil { -+ logrus.Printf("blkio IoTimeRecursive do not match - %s\n", err) -+ t.Fail() -+ } -+} -+ -+func expectThrottlingDataEquals(t *testing.T, expected, actual cgroups.ThrottlingData) { -+ if expected != actual { -+ logrus.Printf("Expected throttling data %v but found %v\n", expected, actual) -+ t.Fail() -+ } -+} -+ -+func expectHugetlbStatEquals(t *testing.T, expected, actual cgroups.HugetlbStats) { -+ if expected != actual { -+ logrus.Printf("Expected hugetlb stats %v but found %v\n", expected, actual) -+ t.Fail() -+ } -+} -+ -+func expectMemoryStatEquals(t *testing.T, expected, actual cgroups.MemoryStats) { -+ expectMemoryDataEquals(t, expected.Usage, actual.Usage) -+ expectMemoryDataEquals(t, expected.SwapUsage, actual.SwapUsage) -+ expectMemoryDataEquals(t, expected.KernelUsage, actual.KernelUsage) -+ -+ for key, expValue := range expected.Stats { -+ actValue, ok := actual.Stats[key] -+ if !ok { -+ logrus.Printf("Expected memory stat key %s not found\n", key) -+ t.Fail() -+ } -+ if expValue != actValue { -+ logrus.Printf("Expected memory stat value %d but found %d\n", expValue, actValue) -+ t.Fail() -+ } -+ } -+} -+ -+func expectMemoryDataEquals(t *testing.T, expected, actual cgroups.MemoryData) { -+ if expected.Usage != actual.Usage { -+ logrus.Printf("Expected memory usage %d but found %d\n", expected.Usage, actual.Usage) -+ t.Fail() -+ } -+ if expected.MaxUsage != actual.MaxUsage { -+ logrus.Printf("Expected memory max usage %d but found %d\n", expected.MaxUsage, actual.MaxUsage) -+ t.Fail() -+ } -+ if expected.Failcnt != actual.Failcnt { -+ logrus.Printf("Expected memory failcnt %d but found %d\n", expected.Failcnt, actual.Failcnt) -+ t.Fail() -+ } -+ if expected.Limit != actual.Limit { -+ logrus.Printf("Expected memory limit %d but found %d\n", expected.Limit, actual.Limit) -+ t.Fail() -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/util_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/util_test.go -new file mode 100644 -index 0000000000..7067e799fb ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/util_test.go -@@ -0,0 +1,67 @@ -+// +build linux -+ -+/* -+Utility for testing cgroup operations. -+ -+Creates a mock of the cgroup filesystem for the duration of the test. -+*/ -+package fs -+ -+import ( -+ "io/ioutil" -+ "os" -+ "path/filepath" -+ "testing" -+ -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+type cgroupTestUtil struct { -+ // cgroup data to use in tests. -+ CgroupData *cgroupData -+ -+ // Path to the mock cgroup directory. -+ CgroupPath string -+ -+ // Temporary directory to store mock cgroup filesystem. -+ tempDir string -+ t *testing.T -+} -+ -+// Creates a new test util for the specified subsystem -+func NewCgroupTestUtil(subsystem string, t *testing.T) *cgroupTestUtil { -+ d := &cgroupData{ -+ config: &configs.Cgroup{}, -+ } -+ d.config.Resources = &configs.Resources{} -+ tempDir, err := ioutil.TempDir("", "cgroup_test") -+ if err != nil { -+ t.Fatal(err) -+ } -+ d.root = tempDir -+ testCgroupPath := filepath.Join(d.root, subsystem) -+ if err != nil { -+ t.Fatal(err) -+ } -+ -+ // Ensure the full mock cgroup path exists. -+ err = os.MkdirAll(testCgroupPath, 0755) -+ if err != nil { -+ t.Fatal(err) -+ } -+ return &cgroupTestUtil{CgroupData: d, CgroupPath: testCgroupPath, tempDir: tempDir, t: t} -+} -+ -+func (c *cgroupTestUtil) cleanup() { -+ os.RemoveAll(c.tempDir) -+} -+ -+// Write the specified contents on the mock of the specified cgroup files. -+func (c *cgroupTestUtil) writeFileContents(fileContents map[string]string) { -+ for file, contents := range fileContents { -+ err := writeFile(c.CgroupPath, file, contents) -+ if err != nil { -+ c.t.Fatal(err) -+ } -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils.go -new file mode 100644 -index 0000000000..5ff0a16150 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils.go -@@ -0,0 +1,78 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "errors" -+ "fmt" -+ "io/ioutil" -+ "path/filepath" -+ "strconv" -+ "strings" -+) -+ -+var ( -+ ErrNotValidFormat = errors.New("line is not a valid key value format") -+) -+ -+// Saturates negative values at zero and returns a uint64. -+// Due to kernel bugs, some of the memory cgroup stats can be negative. -+func parseUint(s string, base, bitSize int) (uint64, error) { -+ value, err := strconv.ParseUint(s, base, bitSize) -+ if err != nil { -+ intValue, intErr := strconv.ParseInt(s, base, bitSize) -+ // 1. Handle negative values greater than MinInt64 (and) -+ // 2. Handle negative values lesser than MinInt64 -+ if intErr == nil && intValue < 0 { -+ return 0, nil -+ } else if intErr != nil && intErr.(*strconv.NumError).Err == strconv.ErrRange && intValue < 0 { -+ return 0, nil -+ } -+ -+ return value, err -+ } -+ -+ return value, nil -+} -+ -+// Parses a cgroup param and returns as name, value -+// i.e. "io_service_bytes 1234" will return as io_service_bytes, 1234 -+func getCgroupParamKeyValue(t string) (string, uint64, error) { -+ parts := strings.Fields(t) -+ switch len(parts) { -+ case 2: -+ value, err := parseUint(parts[1], 10, 64) -+ if err != nil { -+ return "", 0, fmt.Errorf("unable to convert param value (%q) to uint64: %v", parts[1], err) -+ } -+ -+ return parts[0], value, nil -+ default: -+ return "", 0, ErrNotValidFormat -+ } -+} -+ -+// Gets a single uint64 value from the specified cgroup file. -+func getCgroupParamUint(cgroupPath, cgroupFile string) (uint64, error) { -+ fileName := filepath.Join(cgroupPath, cgroupFile) -+ contents, err := ioutil.ReadFile(fileName) -+ if err != nil { -+ return 0, err -+ } -+ -+ res, err := parseUint(strings.TrimSpace(string(contents)), 10, 64) -+ if err != nil { -+ return res, fmt.Errorf("unable to parse %q as a uint from Cgroup file %q", string(contents), fileName) -+ } -+ return res, nil -+} -+ -+// Gets a string value from the specified cgroup file -+func getCgroupParamString(cgroupPath, cgroupFile string) (string, error) { -+ contents, err := ioutil.ReadFile(filepath.Join(cgroupPath, cgroupFile)) -+ if err != nil { -+ return "", err -+ } -+ -+ return strings.TrimSpace(string(contents)), nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils_test.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils_test.go -new file mode 100644 -index 0000000000..99cdc18e07 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/fs/utils_test.go -@@ -0,0 +1,97 @@ -+// +build linux -+ -+package fs -+ -+import ( -+ "io/ioutil" -+ "math" -+ "os" -+ "path/filepath" -+ "strconv" -+ "testing" -+) -+ -+const ( -+ cgroupFile = "cgroup.file" -+ floatValue = 2048.0 -+ floatString = "2048" -+) -+ -+func TestGetCgroupParamsInt(t *testing.T) { -+ // Setup tempdir. -+ tempDir, err := ioutil.TempDir("", "cgroup_utils_test") -+ if err != nil { -+ t.Fatal(err) -+ } -+ defer os.RemoveAll(tempDir) -+ tempFile := filepath.Join(tempDir, cgroupFile) -+ -+ // Success. -+ err = ioutil.WriteFile(tempFile, []byte(floatString), 0755) -+ if err != nil { -+ t.Fatal(err) -+ } -+ value, err := getCgroupParamUint(tempDir, cgroupFile) -+ if err != nil { -+ t.Fatal(err) -+ } else if value != floatValue { -+ t.Fatalf("Expected %d to equal %f", value, floatValue) -+ } -+ -+ // Success with new line. -+ err = ioutil.WriteFile(tempFile, []byte(floatString+"\n"), 0755) -+ if err != nil { -+ t.Fatal(err) -+ } -+ value, err = getCgroupParamUint(tempDir, cgroupFile) -+ if err != nil { -+ t.Fatal(err) -+ } else if value != floatValue { -+ t.Fatalf("Expected %d to equal %f", value, floatValue) -+ } -+ -+ // Success with negative values -+ err = ioutil.WriteFile(tempFile, []byte("-12345"), 0755) -+ if err != nil { -+ t.Fatal(err) -+ } -+ value, err = getCgroupParamUint(tempDir, cgroupFile) -+ if err != nil { -+ t.Fatal(err) -+ } else if value != 0 { -+ t.Fatalf("Expected %d to equal %d", value, 0) -+ } -+ -+ // Success with negative values lesser than min int64 -+ s := strconv.FormatFloat(math.MinInt64, 'f', -1, 64) -+ err = ioutil.WriteFile(tempFile, []byte(s), 0755) -+ if err != nil { -+ t.Fatal(err) -+ } -+ value, err = getCgroupParamUint(tempDir, cgroupFile) -+ if err != nil { -+ t.Fatal(err) -+ } else if value != 0 { -+ t.Fatalf("Expected %d to equal %d", value, 0) -+ } -+ -+ // Not a float. -+ err = ioutil.WriteFile(tempFile, []byte("not-a-float"), 0755) -+ if err != nil { -+ t.Fatal(err) -+ } -+ _, err = getCgroupParamUint(tempDir, cgroupFile) -+ if err == nil { -+ t.Fatal("Expecting error, got none") -+ } -+ -+ // Unknown file. -+ err = os.Remove(tempFile) -+ if err != nil { -+ t.Fatal(err) -+ } -+ _, err = getCgroupParamUint(tempDir, cgroupFile) -+ if err == nil { -+ t.Fatal("Expecting error, got none") -+ } -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/rootless/rootless.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/rootless/rootless.go -new file mode 100644 -index 0000000000..b1efbfd999 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/rootless/rootless.go -@@ -0,0 +1,128 @@ -+// +build linux -+ -+package rootless -+ -+import ( -+ "fmt" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/cgroups/fs" -+ "github.com/opencontainers/runc/libcontainer/configs" -+ "github.com/opencontainers/runc/libcontainer/configs/validate" -+) -+ -+// TODO: This is copied from libcontainer/cgroups/fs, which duplicates this code -+// needlessly. We should probably export this list. -+ -+var subsystems = []subsystem{ -+ &fs.CpusetGroup{}, -+ &fs.DevicesGroup{}, -+ &fs.MemoryGroup{}, -+ &fs.CpuGroup{}, -+ &fs.CpuacctGroup{}, -+ &fs.PidsGroup{}, -+ &fs.BlkioGroup{}, -+ &fs.HugetlbGroup{}, -+ &fs.NetClsGroup{}, -+ &fs.NetPrioGroup{}, -+ &fs.PerfEventGroup{}, -+ &fs.FreezerGroup{}, -+ &fs.NameGroup{GroupName: "name=systemd"}, -+} -+ -+type subsystem interface { -+ // Name returns the name of the subsystem. -+ Name() string -+ -+ // Returns the stats, as 'stats', corresponding to the cgroup under 'path'. -+ GetStats(path string, stats *cgroups.Stats) error -+} -+ -+// The noop cgroup manager is used for rootless containers, because we currently -+// cannot manage cgroups if we are in a rootless setup. This manager is chosen -+// by factory if we are in rootless mode. We error out if any cgroup options are -+// set in the config -- this may change in the future with upcoming kernel features -+// like the cgroup namespace. -+ -+type Manager struct { -+ Cgroups *configs.Cgroup -+ Paths map[string]string -+} -+ -+func (m *Manager) Apply(pid int) error { -+ // If there are no cgroup settings, there's nothing to do. -+ if m.Cgroups == nil { -+ return nil -+ } -+ -+ // We can't set paths. -+ // TODO(cyphar): Implement the case where the runner of a rootless container -+ // owns their own cgroup, which would allow us to set up a -+ // cgroup for each path. -+ if m.Cgroups.Paths != nil { -+ return fmt.Errorf("cannot change cgroup path in rootless container") -+ } -+ -+ // We load the paths into the manager. -+ paths := make(map[string]string) -+ for _, sys := range subsystems { -+ name := sys.Name() -+ -+ path, err := cgroups.GetOwnCgroupPath(name) -+ if err != nil { -+ // Ignore paths we couldn't resolve. -+ continue -+ } -+ -+ paths[name] = path -+ } -+ -+ m.Paths = paths -+ return nil -+} -+ -+func (m *Manager) GetPaths() map[string]string { -+ return m.Paths -+} -+ -+func (m *Manager) Set(container *configs.Config) error { -+ // We have to re-do the validation here, since someone might decide to -+ // update a rootless container. -+ return validate.New().Validate(container) -+} -+ -+func (m *Manager) GetPids() ([]int, error) { -+ dir, err := cgroups.GetOwnCgroupPath("devices") -+ if err != nil { -+ return nil, err -+ } -+ return cgroups.GetPids(dir) -+} -+ -+func (m *Manager) GetAllPids() ([]int, error) { -+ dir, err := cgroups.GetOwnCgroupPath("devices") -+ if err != nil { -+ return nil, err -+ } -+ return cgroups.GetAllPids(dir) -+} -+ -+func (m *Manager) GetStats() (*cgroups.Stats, error) { -+ // TODO(cyphar): We can make this work if we figure out a way to allow usage -+ // of cgroups with a rootless container. While this doesn't -+ // actually require write access to a cgroup directory, the -+ // statistics are not useful if they can be affected by -+ // non-container processes. -+ return nil, fmt.Errorf("cannot get cgroup stats in rootless container") -+} -+ -+func (m *Manager) Freeze(state configs.FreezerState) error { -+ // TODO(cyphar): We can make this work if we figure out a way to allow usage -+ // of cgroups with a rootless container. -+ return fmt.Errorf("cannot use freezer cgroup in rootless container") -+} -+ -+func (m *Manager) Destroy() error { -+ // We don't have to do anything here because we didn't do any setup. -+ return nil -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go -index 8eeedc55b0..e11c5c7416 100644 ---- a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/stats.go -@@ -64,6 +64,13 @@ type PidsStats struct { - Limit uint64 `json:"limit,omitempty"` - } - -+type FilesStats struct { -+ // number of pids in the cgroup -+ Usage uint64 `json:"usage,omitempty"` -+ // active pids hard limit -+ Limit uint64 `json:"limit,omitempty"` -+} -+ - type BlkioStatEntry struct { - Major uint64 `json:"major,omitempty"` - Minor uint64 `json:"minor,omitempty"` -@@ -96,6 +103,7 @@ type Stats struct { - CpuStats CpuStats `json:"cpu_stats,omitempty"` - MemoryStats MemoryStats `json:"memory_stats,omitempty"` - PidsStats PidsStats `json:"pids_stats,omitempty"` -+ FilesStats FilesStats `json:"files_stats,omitempty"` - BlkioStats BlkioStats `json:"blkio_stats,omitempty"` - // the map is in the format "size of hugepage: stats of the hugepage" - HugetlbStats map[string]HugetlbStats `json:"hugetlb_stats,omitempty"` -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_nosystemd.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_nosystemd.go -new file mode 100644 -index 0000000000..7de9ae6050 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_nosystemd.go -@@ -0,0 +1,55 @@ -+// +build !linux -+ -+package systemd -+ -+import ( -+ "fmt" -+ -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+type Manager struct { -+ Cgroups *configs.Cgroup -+ Paths map[string]string -+} -+ -+func UseSystemd() bool { -+ return false -+} -+ -+func (m *Manager) Apply(pid int) error { -+ return fmt.Errorf("Systemd not supported") -+} -+ -+func (m *Manager) GetPids() ([]int, error) { -+ return nil, fmt.Errorf("Systemd not supported") -+} -+ -+func (m *Manager) GetAllPids() ([]int, error) { -+ return nil, fmt.Errorf("Systemd not supported") -+} -+ -+func (m *Manager) Destroy() error { -+ return fmt.Errorf("Systemd not supported") -+} -+ -+func (m *Manager) GetPaths() map[string]string { -+ return nil -+} -+ -+func (m *Manager) GetStats() (*cgroups.Stats, error) { -+ return nil, fmt.Errorf("Systemd not supported") -+} -+ -+func (m *Manager) Set(container *configs.Config) error { -+ return nil, fmt.Errorf("Systemd not supported") -+} -+ -+func (m *Manager) Freeze(state configs.FreezerState) error { -+ return fmt.Errorf("Systemd not supported") -+} -+ -+func Freeze(c *configs.Cgroup, state configs.FreezerState) error { -+ return fmt.Errorf("Systemd not supported") -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go -new file mode 100644 -index 0000000000..0411b72390 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/cgroups/systemd/apply_systemd.go -@@ -0,0 +1,556 @@ -+// +build linux -+ -+package systemd -+ -+import ( -+ "errors" -+ "fmt" -+ "os" -+ "path/filepath" -+ "strings" -+ "sync" -+ "time" -+ -+ systemdDbus "github.com/coreos/go-systemd/dbus" -+ systemdUtil "github.com/coreos/go-systemd/util" -+ "github.com/godbus/dbus" -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+ "github.com/opencontainers/runc/libcontainer/cgroups/fs" -+ "github.com/opencontainers/runc/libcontainer/configs" -+) -+ -+type Manager struct { -+ mu sync.Mutex -+ Cgroups *configs.Cgroup -+ Paths map[string]string -+} -+ -+type subsystem interface { -+ // Name returns the name of the subsystem. -+ Name() string -+ // Returns the stats, as 'stats', corresponding to the cgroup under 'path'. -+ GetStats(path string, stats *cgroups.Stats) error -+ // Set the cgroup represented by cgroup. -+ Set(path string, cgroup *configs.Cgroup) error -+} -+ -+var errSubsystemDoesNotExist = errors.New("cgroup: subsystem does not exist") -+ -+type subsystemSet []subsystem -+ -+func (s subsystemSet) Get(name string) (subsystem, error) { -+ for _, ss := range s { -+ if ss.Name() == name { -+ return ss, nil -+ } -+ } -+ return nil, errSubsystemDoesNotExist -+} -+ -+var subsystems = subsystemSet{ -+ &fs.CpusetGroup{}, -+ &fs.DevicesGroup{}, -+ &fs.MemoryGroup{}, -+ &fs.CpuGroup{}, -+ &fs.CpuacctGroup{}, -+ &fs.PidsGroup{}, -+ &fs.FilesGroup{}, -+ &fs.BlkioGroup{}, -+ &fs.HugetlbGroup{}, -+ &fs.PerfEventGroup{}, -+ &fs.FreezerGroup{}, -+ &fs.NetPrioGroup{}, -+ &fs.NetClsGroup{}, -+ &fs.NameGroup{GroupName: "name=systemd"}, -+} -+ -+const ( -+ testScopeWait = 4 -+ testSliceWait = 4 -+) -+ -+var ( -+ connLock sync.Mutex -+ theConn *systemdDbus.Conn -+ hasStartTransientUnit bool -+ hasStartTransientSliceUnit bool -+ hasTransientDefaultDependencies bool -+ hasDelegate bool -+) -+ -+func newProp(name string, units interface{}) systemdDbus.Property { -+ return systemdDbus.Property{ -+ Name: name, -+ Value: dbus.MakeVariant(units), -+ } -+} -+ -+func UseSystemd() bool { -+ if !systemdUtil.IsRunningSystemd() { -+ return false -+ } -+ -+ connLock.Lock() -+ defer connLock.Unlock() -+ -+ if theConn == nil { -+ var err error -+ theConn, err = systemdDbus.New() -+ if err != nil { -+ return false -+ } -+ -+ // Assume we have StartTransientUnit -+ hasStartTransientUnit = true -+ -+ // But if we get UnknownMethod error we don't -+ if _, err := theConn.StartTransientUnit("test.scope", "invalid", nil, nil); err != nil { -+ if dbusError, ok := err.(dbus.Error); ok { -+ if dbusError.Name == "org.freedesktop.DBus.Error.UnknownMethod" { -+ hasStartTransientUnit = false -+ return hasStartTransientUnit -+ } -+ } -+ } -+ -+ // Ensure the scope name we use doesn't exist. Use the Pid to -+ // avoid collisions between multiple libcontainer users on a -+ // single host. -+ scope := fmt.Sprintf("libcontainer-%d-systemd-test-default-dependencies.scope", os.Getpid()) -+ testScopeExists := true -+ for i := 0; i <= testScopeWait; i++ { -+ if _, err := theConn.StopUnit(scope, "replace", nil); err != nil { -+ if dbusError, ok := err.(dbus.Error); ok { -+ if strings.Contains(dbusError.Name, "org.freedesktop.systemd1.NoSuchUnit") { -+ testScopeExists = false -+ break -+ } -+ } -+ } -+ time.Sleep(time.Millisecond) -+ } -+ -+ // Bail out if we can't kill this scope without testing for DefaultDependencies -+ if testScopeExists { -+ return hasStartTransientUnit -+ } -+ -+ // Assume StartTransientUnit on a scope allows DefaultDependencies -+ hasTransientDefaultDependencies = true -+ ddf := newProp("DefaultDependencies", false) -+ if _, err := theConn.StartTransientUnit(scope, "replace", []systemdDbus.Property{ddf}, nil); err != nil { -+ if dbusError, ok := err.(dbus.Error); ok { -+ if strings.Contains(dbusError.Name, "org.freedesktop.DBus.Error.PropertyReadOnly") { -+ hasTransientDefaultDependencies = false -+ } -+ } -+ } -+ -+ // Not critical because of the stop unit logic above. -+ theConn.StopUnit(scope, "replace", nil) -+ -+ // Assume StartTransientUnit on a scope allows Delegate -+ hasDelegate = true -+ dl := newProp("Delegate", true) -+ if _, err := theConn.StartTransientUnit(scope, "replace", []systemdDbus.Property{dl}, nil); err != nil { -+ if dbusError, ok := err.(dbus.Error); ok { -+ if strings.Contains(dbusError.Name, "org.freedesktop.DBus.Error.PropertyReadOnly") { -+ hasDelegate = false -+ } -+ } -+ } -+ -+ // Assume we have the ability to start a transient unit as a slice -+ // This was broken until systemd v229, but has been back-ported on RHEL environments >= 219 -+ // For details, see: https://bugzilla.redhat.com/show_bug.cgi?id=1370299 -+ hasStartTransientSliceUnit = true -+ -+ // To ensure simple clean-up, we create a slice off the root with no hierarchy -+ slice := fmt.Sprintf("libcontainer_%d_systemd_test_default.slice", os.Getpid()) -+ if _, err := theConn.StartTransientUnit(slice, "replace", nil, nil); err != nil { -+ if _, ok := err.(dbus.Error); ok { -+ hasStartTransientSliceUnit = false -+ } -+ } -+ -+ for i := 0; i <= testSliceWait; i++ { -+ if _, err := theConn.StopUnit(slice, "replace", nil); err != nil { -+ if dbusError, ok := err.(dbus.Error); ok { -+ if strings.Contains(dbusError.Name, "org.freedesktop.systemd1.NoSuchUnit") { -+ hasStartTransientSliceUnit = false -+ break -+ } -+ } -+ } else { -+ break -+ } -+ time.Sleep(time.Millisecond) -+ } -+ -+ // Not critical because of the stop unit logic above. -+ theConn.StopUnit(scope, "replace", nil) -+ theConn.StopUnit(slice, "replace", nil) -+ } -+ return hasStartTransientUnit -+} -+ -+func (m *Manager) Apply(pid int) error { -+ var ( -+ c = m.Cgroups -+ unitName = getUnitName(c) -+ slice = "system.slice" -+ properties []systemdDbus.Property -+ ) -+ -+ if c.Paths != nil { -+ paths := make(map[string]string) -+ for name, path := range c.Paths { -+ _, err := getSubsystemPath(m.Cgroups, name) -+ if err != nil { -+ // Don't fail if a cgroup hierarchy was not found, just skip this subsystem -+ if cgroups.IsNotFound(err) { -+ continue -+ } -+ return err -+ } -+ paths[name] = path -+ } -+ m.Paths = paths -+ return cgroups.EnterPid(m.Paths, pid) -+ } -+ -+ if c.Parent != "" { -+ slice = c.Parent -+ } -+ -+ properties = append(properties, systemdDbus.PropDescription("libcontainer container "+c.Name)) -+ -+ // if we create a slice, the parent is defined via a Wants= -+ if strings.HasSuffix(unitName, ".slice") { -+ // This was broken until systemd v229, but has been back-ported on RHEL environments >= 219 -+ if !hasStartTransientSliceUnit { -+ return fmt.Errorf("systemd version does not support ability to start a slice as transient unit") -+ } -+ properties = append(properties, systemdDbus.PropWants(slice)) -+ } else { -+ // otherwise, we use Slice= -+ properties = append(properties, systemdDbus.PropSlice(slice)) -+ } -+ -+ // only add pid if its valid, -1 is used w/ general slice creation. -+ if pid != -1 { -+ properties = append(properties, newProp("PIDs", []uint32{uint32(pid)})) -+ } -+ -+ if hasDelegate { -+ // This is only supported on systemd versions 218 and above. -+ properties = append(properties, newProp("Delegate", true)) -+ } -+ -+ // Always enable accounting, this gets us the same behaviour as the fs implementation, -+ // plus the kernel has some problems with joining the memory cgroup at a later time. -+ properties = append(properties, -+ newProp("MemoryAccounting", true), -+ newProp("CPUAccounting", true), -+ newProp("BlockIOAccounting", true)) -+ -+ if hasTransientDefaultDependencies { -+ properties = append(properties, -+ newProp("DefaultDependencies", false)) -+ } -+ -+ if c.Resources.Memory != 0 { -+ properties = append(properties, -+ newProp("MemoryLimit", c.Resources.Memory)) -+ } -+ -+ if c.Resources.CpuShares != 0 { -+ properties = append(properties, -+ newProp("CPUShares", c.Resources.CpuShares)) -+ } -+ -+ // cpu.cfs_quota_us and cpu.cfs_period_us are controlled by systemd. -+ if c.Resources.CpuQuota != 0 && c.Resources.CpuPeriod != 0 { -+ cpuQuotaPerSecUSec := uint64(c.Resources.CpuQuota*1000000) / c.Resources.CpuPeriod -+ properties = append(properties, -+ newProp("CPUQuotaPerSecUSec", cpuQuotaPerSecUSec)) -+ } -+ -+ if c.Resources.BlkioWeight != 0 { -+ properties = append(properties, -+ newProp("BlockIOWeight", uint64(c.Resources.BlkioWeight))) -+ } -+ -+ // We have to set kernel memory here, as we can't change it once -+ // processes have been attached to the cgroup. -+ if c.Resources.KernelMemory != 0 { -+ if err := setKernelMemory(c); err != nil { -+ return err -+ } -+ } -+ -+ if _, err := theConn.StartTransientUnit(unitName, "replace", properties, nil); err != nil && !isUnitExists(err) { -+ return err -+ } -+ -+ if err := joinCgroups(c, pid); err != nil { -+ return err -+ } -+ -+ paths := make(map[string]string) -+ for _, s := range subsystems { -+ subsystemPath, err := getSubsystemPath(m.Cgroups, s.Name()) -+ if err != nil { -+ // Don't fail if a cgroup hierarchy was not found, just skip this subsystem -+ if cgroups.IsNotFound(err) { -+ continue -+ } -+ return err -+ } -+ paths[s.Name()] = subsystemPath -+ } -+ m.Paths = paths -+ return nil -+} -+ -+func (m *Manager) Destroy() error { -+ if m.Cgroups.Paths != nil { -+ return nil -+ } -+ m.mu.Lock() -+ defer m.mu.Unlock() -+ theConn.StopUnit(getUnitName(m.Cgroups), "replace", nil) -+ if err := cgroups.RemovePaths(m.Paths); err != nil { -+ return err -+ } -+ m.Paths = make(map[string]string) -+ return nil -+} -+ -+func (m *Manager) GetPaths() map[string]string { -+ m.mu.Lock() -+ paths := m.Paths -+ m.mu.Unlock() -+ return paths -+} -+ -+func join(c *configs.Cgroup, subsystem string, pid int) (string, error) { -+ path, err := getSubsystemPath(c, subsystem) -+ if err != nil { -+ return "", err -+ } -+ if err := os.MkdirAll(path, 0755); err != nil { -+ return "", err -+ } -+ if err := cgroups.WriteCgroupProc(path, pid); err != nil { -+ return "", err -+ } -+ return path, nil -+} -+ -+func joinCgroups(c *configs.Cgroup, pid int) error { -+ for _, sys := range subsystems { -+ name := sys.Name() -+ switch name { -+ case "name=systemd": -+ // let systemd handle this -+ break -+ case "cpuset": -+ path, err := getSubsystemPath(c, name) -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ s := &fs.CpusetGroup{} -+ if err := s.ApplyDir(path, c, pid); err != nil { -+ return err -+ } -+ break -+ default: -+ _, err := join(c, name, pid) -+ if err != nil { -+ // Even if it's `not found` error, we'll return err -+ // because devices cgroup is hard requirement for -+ // container security. -+ if name == "devices" { -+ return err -+ } -+ // For other subsystems, omit the `not found` error -+ // because they are optional. -+ if !cgroups.IsNotFound(err) { -+ return err -+ } -+ } -+ } -+ } -+ -+ return nil -+} -+ -+// systemd represents slice hierarchy using `-`, so we need to follow suit when -+// generating the path of slice. Essentially, test-a-b.slice becomes -+// test.slice/test-a.slice/test-a-b.slice. -+func ExpandSlice(slice string) (string, error) { -+ suffix := ".slice" -+ // Name has to end with ".slice", but can't be just ".slice". -+ if len(slice) < len(suffix) || !strings.HasSuffix(slice, suffix) { -+ return "", fmt.Errorf("invalid slice name: %s", slice) -+ } -+ -+ // Path-separators are not allowed. -+ if strings.Contains(slice, "/") { -+ return "", fmt.Errorf("invalid slice name: %s", slice) -+ } -+ -+ var path, prefix string -+ sliceName := strings.TrimSuffix(slice, suffix) -+ // if input was -.slice, we should just return root now -+ if sliceName == "-" { -+ return "/", nil -+ } -+ for _, component := range strings.Split(sliceName, "-") { -+ // test--a.slice isn't permitted, nor is -test.slice. -+ if component == "" { -+ return "", fmt.Errorf("invalid slice name: %s", slice) -+ } -+ -+ // Append the component to the path and to the prefix. -+ path += prefix + component + suffix + "/" -+ prefix += component + "-" -+ } -+ -+ return path, nil -+} -+ -+func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) { -+ mountpoint, err := cgroups.FindCgroupMountpoint(subsystem) -+ if err != nil { -+ return "", err -+ } -+ -+ initPath, err := cgroups.GetInitCgroup(subsystem) -+ if err != nil { -+ return "", err -+ } -+ // if pid 1 is systemd 226 or later, it will be in init.scope, not the root -+ initPath = strings.TrimSuffix(filepath.Clean(initPath), "init.scope") -+ -+ slice := "system.slice" -+ if c.Parent != "" { -+ slice = c.Parent -+ } -+ -+ slice, err = ExpandSlice(slice) -+ if err != nil { -+ return "", err -+ } -+ -+ return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil -+} -+ -+func (m *Manager) Freeze(state configs.FreezerState) error { -+ path, err := getSubsystemPath(m.Cgroups, "freezer") -+ if err != nil { -+ return err -+ } -+ prevState := m.Cgroups.Resources.Freezer -+ m.Cgroups.Resources.Freezer = state -+ freezer, err := subsystems.Get("freezer") -+ if err != nil { -+ return err -+ } -+ err = freezer.Set(path, m.Cgroups) -+ if err != nil { -+ m.Cgroups.Resources.Freezer = prevState -+ return err -+ } -+ return nil -+} -+ -+func (m *Manager) GetPids() ([]int, error) { -+ path, err := getSubsystemPath(m.Cgroups, "devices") -+ if err != nil { -+ return nil, err -+ } -+ return cgroups.GetPids(path) -+} -+ -+func (m *Manager) GetAllPids() ([]int, error) { -+ path, err := getSubsystemPath(m.Cgroups, "devices") -+ if err != nil { -+ return nil, err -+ } -+ return cgroups.GetAllPids(path) -+} -+ -+func (m *Manager) GetStats() (*cgroups.Stats, error) { -+ m.mu.Lock() -+ defer m.mu.Unlock() -+ stats := cgroups.NewStats() -+ for name, path := range m.Paths { -+ sys, err := subsystems.Get(name) -+ if err == errSubsystemDoesNotExist || !cgroups.PathExists(path) { -+ continue -+ } -+ if err := sys.GetStats(path, stats); err != nil { -+ return nil, err -+ } -+ } -+ -+ return stats, nil -+} -+ -+func (m *Manager) Set(container *configs.Config) error { -+ // If Paths are set, then we are just joining cgroups paths -+ // and there is no need to set any values. -+ if m.Cgroups.Paths != nil { -+ return nil -+ } -+ for _, sys := range subsystems { -+ // Get the subsystem path, but don't error out for not found cgroups. -+ path, err := getSubsystemPath(container.Cgroups, sys.Name()) -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ -+ if err := sys.Set(path, container.Cgroups); err != nil { -+ return err -+ } -+ } -+ -+ if m.Paths["cpu"] != "" { -+ if err := fs.CheckCpushares(m.Paths["cpu"], container.Cgroups.Resources.CpuShares); err != nil { -+ return err -+ } -+ } -+ return nil -+} -+ -+func getUnitName(c *configs.Cgroup) string { -+ // by default, we create a scope unless the user explicitly asks for a slice. -+ if !strings.HasSuffix(c.Name, ".slice") { -+ return fmt.Sprintf("%s-%s.scope", c.ScopePrefix, c.Name) -+ } -+ return c.Name -+} -+ -+func setKernelMemory(c *configs.Cgroup) error { -+ path, err := getSubsystemPath(c, "memory") -+ if err != nil && !cgroups.IsNotFound(err) { -+ return err -+ } -+ -+ if err := os.MkdirAll(path, 0755); err != nil { -+ return err -+ } -+ return fs.EnableKernelMemoryAccounting(path) -+} -+ -+// isUnitExists returns true if the error is that a systemd unit already exists. -+func isUnitExists(err error) bool { -+ if err != nil { -+ if dbusError, ok := err.(dbus.Error); ok { -+ return strings.Contains(dbusError.Name, "org.freedesktop.systemd1.UnitExists") -+ } -+ } -+ return false -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go -index e15a662f52..c5634f597e 100644 ---- a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go -@@ -81,6 +81,9 @@ type Resources struct { - // Process limit; set <= `0' to disable limit. - PidsLimit int64 `json:"pids_limit"` - -+ // Process open files limit. -+ FilesLimit int64 `json:"files_limit"` -+ - // Specifies per cgroup weight, range is from 10 to 1000. - BlkioWeight uint16 `json:"blkio_weight"` - -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go -new file mode 100644 -index 0000000000..2cbb6491a7 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go -@@ -0,0 +1,95 @@ -+// +build linux -+ -+package utils -+ -+/* -+ * Copyright 2016, 2017 SUSE LLC -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+import ( -+ "fmt" -+ "os" -+ -+ "golang.org/x/sys/unix" -+) -+ -+// MaxSendfdLen is the maximum length of the name of a file descriptor being -+// sent using SendFd. The name of the file handle returned by RecvFd will never -+// be larger than this value. -+const MaxNameLen = 4096 -+ -+// oobSpace is the size of the oob slice required to store a single FD. Note -+// that unix.UnixRights appears to make the assumption that fd is always int32, -+// so sizeof(fd) = 4. -+var oobSpace = unix.CmsgSpace(4) -+ -+// RecvFd waits for a file descriptor to be sent over the given AF_UNIX -+// socket. The file name of the remote file descriptor will be recreated -+// locally (it is sent as non-auxiliary data in the same payload). -+func RecvFd(socket *os.File) (*os.File, error) { -+ // For some reason, unix.Recvmsg uses the length rather than the capacity -+ // when passing the msg_controllen and other attributes to recvmsg. So we -+ // have to actually set the length. -+ name := make([]byte, MaxNameLen) -+ oob := make([]byte, oobSpace) -+ -+ sockfd := socket.Fd() -+ n, oobn, _, _, err := unix.Recvmsg(int(sockfd), name, oob, 0) -+ if err != nil { -+ return nil, err -+ } -+ -+ if n >= MaxNameLen || oobn != oobSpace { -+ return nil, fmt.Errorf("recvfd: incorrect number of bytes read (n=%d oobn=%d)", n, oobn) -+ } -+ -+ // Truncate. -+ name = name[:n] -+ oob = oob[:oobn] -+ -+ scms, err := unix.ParseSocketControlMessage(oob) -+ if err != nil { -+ return nil, err -+ } -+ if len(scms) != 1 { -+ return nil, fmt.Errorf("recvfd: number of SCMs is not 1: %d", len(scms)) -+ } -+ scm := scms[0] -+ -+ fds, err := unix.ParseUnixRights(&scm) -+ if err != nil { -+ return nil, err -+ } -+ if len(fds) != 1 { -+ return nil, fmt.Errorf("recvfd: number of fds is not 1: %d", len(fds)) -+ } -+ fd := uintptr(fds[0]) -+ -+ return os.NewFile(fd, string(name)), nil -+} -+ -+// SendFd sends a file descriptor over the given AF_UNIX socket. In -+// addition, the file.Name() of the given file will also be sent as -+// non-auxiliary data in the same payload (allowing to send contextual -+// information for a file descriptor). -+func SendFd(socket, file *os.File) error { -+ name := []byte(file.Name()) -+ if len(name) >= MaxNameLen { -+ return fmt.Errorf("sendfd: filename too long: %s", file.Name()) -+ } -+ oob := unix.UnixRights(int(file.Fd())) -+ -+ return unix.Sendmsg(int(socket.Fd()), name, oob, nil, 0) -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go -new file mode 100644 -index 0000000000..2b35b9a7b6 ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go -@@ -0,0 +1,126 @@ -+package utils -+ -+import ( -+ "crypto/rand" -+ "encoding/hex" -+ "encoding/json" -+ "io" -+ "os" -+ "path/filepath" -+ "strings" -+ "syscall" -+ "unsafe" -+) -+ -+const ( -+ exitSignalOffset = 128 -+) -+ -+// GenerateRandomName returns a new name joined with a prefix. This size -+// specified is used to truncate the randomly generated value -+func GenerateRandomName(prefix string, size int) (string, error) { -+ id := make([]byte, 32) -+ if _, err := io.ReadFull(rand.Reader, id); err != nil { -+ return "", err -+ } -+ if size > 64 { -+ size = 64 -+ } -+ return prefix + hex.EncodeToString(id)[:size], nil -+} -+ -+// ResolveRootfs ensures that the current working directory is -+// not a symlink and returns the absolute path to the rootfs -+func ResolveRootfs(uncleanRootfs string) (string, error) { -+ rootfs, err := filepath.Abs(uncleanRootfs) -+ if err != nil { -+ return "", err -+ } -+ return filepath.EvalSymlinks(rootfs) -+} -+ -+// ExitStatus returns the correct exit status for a process based on if it -+// was signaled or exited cleanly -+func ExitStatus(status syscall.WaitStatus) int { -+ if status.Signaled() { -+ return exitSignalOffset + int(status.Signal()) -+ } -+ return status.ExitStatus() -+} -+ -+// WriteJSON writes the provided struct v to w using standard json marshaling -+func WriteJSON(w io.Writer, v interface{}) error { -+ data, err := json.Marshal(v) -+ if err != nil { -+ return err -+ } -+ _, err = w.Write(data) -+ return err -+} -+ -+// CleanPath makes a path safe for use with filepath.Join. This is done by not -+// only cleaning the path, but also (if the path is relative) adding a leading -+// '/' and cleaning it (then removing the leading '/'). This ensures that a -+// path resulting from prepending another path will always resolve to lexically -+// be a subdirectory of the prefixed path. This is all done lexically, so paths -+// that include symlinks won't be safe as a result of using CleanPath. -+func CleanPath(path string) string { -+ // Deal with empty strings nicely. -+ if path == "" { -+ return "" -+ } -+ -+ // Ensure that all paths are cleaned (especially problematic ones like -+ // "/../../../../../" which can cause lots of issues). -+ path = filepath.Clean(path) -+ -+ // If the path isn't absolute, we need to do more processing to fix paths -+ // such as "../../../..//some/path". We also shouldn't convert absolute -+ // paths to relative ones. -+ if !filepath.IsAbs(path) { -+ path = filepath.Clean(string(os.PathSeparator) + path) -+ // This can't fail, as (by definition) all paths are relative to root. -+ path, _ = filepath.Rel(string(os.PathSeparator), path) -+ } -+ -+ // Clean the path again for good measure. -+ return filepath.Clean(path) -+} -+ -+// SearchLabels searches a list of key-value pairs for the provided key and -+// returns the corresponding value. The pairs must be separated with '='. -+func SearchLabels(labels []string, query string) string { -+ for _, l := range labels { -+ parts := strings.SplitN(l, "=", 2) -+ if len(parts) < 2 { -+ continue -+ } -+ if parts[0] == query { -+ return parts[1] -+ } -+ } -+ return "" -+} -+ -+// Annotations returns the bundle path and user defined annotations from the -+// libcontainer state. We need to remove the bundle because that is a label -+// added by libcontainer. -+func Annotations(labels []string) (bundle string, userAnnotations map[string]string) { -+ userAnnotations = make(map[string]string) -+ for _, l := range labels { -+ parts := strings.SplitN(l, "=", 2) -+ if len(parts) < 2 { -+ continue -+ } -+ if parts[0] == "bundle" { -+ bundle = parts[1] -+ } else { -+ userAnnotations[parts[0]] = parts[1] -+ } -+ } -+ return -+} -+ -+func GetIntSize() int { -+ return int(unsafe.Sizeof(1)) -+} -diff --git a/components/engine/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go -new file mode 100644 -index 0000000000..7b798cc79d ---- /dev/null -+++ b/components/engine/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go -@@ -0,0 +1,43 @@ -+// +build !windows -+ -+package utils -+ -+import ( -+ "io/ioutil" -+ "os" -+ "strconv" -+ "syscall" -+) -+ -+func CloseExecFrom(minFd int) error { -+ fdList, err := ioutil.ReadDir("/proc/self/fd") -+ if err != nil { -+ return err -+ } -+ for _, fi := range fdList { -+ fd, err := strconv.Atoi(fi.Name()) -+ if err != nil { -+ // ignore non-numeric file names -+ continue -+ } -+ -+ if fd < minFd { -+ // ignore descriptors lower than our specified minimum -+ continue -+ } -+ -+ // intentionally ignore errors from syscall.CloseOnExec -+ syscall.CloseOnExec(fd) -+ // the cases where this might fail are basically file descriptors that have already been closed (including and especially the one that was created when ioutil.ReadDir did the "opendir" syscall) -+ } -+ return nil -+} -+ -+// NewSockPair returns a new unix socket pair -+func NewSockPair(name string) (parent *os.File, child *os.File, err error) { -+ fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0) -+ if err != nil { -+ return nil, nil, err -+ } -+ return os.NewFile(uintptr(fds[1]), name+"-p"), os.NewFile(uintptr(fds[0]), name+"-c"), nil -+} --- -2.17.1 - diff --git a/patch/0068-pause-fix-docker-stop-stuck-on-paused-contain.patch b/patch/0068-pause-fix-docker-stop-stuck-on-paused-contain.patch deleted file mode 100644 index c184840..0000000 --- a/patch/0068-pause-fix-docker-stop-stuck-on-paused-contain.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 634d7c920176c726b8d32d8aee50c8073f4892a3 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Sun, 20 Jan 2019 15:35:57 +0800 -Subject: [PATCH 068/111] pause: fix docker stop stuck on paused - container - -reason: docker-18.09 support docker stop while container is paused. -ref 7aed75f09c * Allow stopping of paused container. - -now docker function is moved to docker, so we still have to check -container paused status. - -Change-Id: I60731c76808abb5a76daf96c2aba656d73a87e96 -Signed-off-by: jingrui ---- - components/engine/daemon/kill.go | 5 +++++ - components/engine/daemon/unpause.go | 5 +++++ - 2 files changed, 10 insertions(+) - -diff --git a/components/engine/daemon/kill.go b/components/engine/daemon/kill.go -index 3e6457e952..5b2e497604 100644 ---- a/components/engine/daemon/kill.go -+++ b/components/engine/daemon/kill.go -@@ -66,6 +66,11 @@ func (daemon *Daemon) killWithSignal(container *containerpkg.Container, sig int) - - daemon.stopHealthchecks(container) - -+ // We could unpause the container for them rather than returning this error -+ if container.Paused { -+ return fmt.Errorf("Container %s is paused. Unpause the container before stopping or killing", container.ID) -+ } -+ - if !container.Running { - return errNotRunning(container.ID) - } -diff --git a/components/engine/daemon/unpause.go b/components/engine/daemon/unpause.go -index 290d2b1d0c..2d3c056566 100644 ---- a/components/engine/daemon/unpause.go -+++ b/components/engine/daemon/unpause.go -@@ -23,6 +23,11 @@ func (daemon *Daemon) containerUnpause(container *container.Container) error { - container.Lock() - defer container.Unlock() - -+ // We cannot unpause the container which is not running -+ if !container.Running { -+ return fmt.Errorf("Container %s is not running", container.ID) -+ } -+ - // We cannot unpause the container which is not paused - if !container.Paused { - return fmt.Errorf("Container %s is not paused", container.ID) --- -2.17.1 - diff --git a/patch/0069-pause-fix-log-pause-unpause-event-twice.patch b/patch/0069-pause-fix-log-pause-unpause-event-twice.patch deleted file mode 100644 index b7b6285..0000000 --- a/patch/0069-pause-fix-log-pause-unpause-event-twice.patch +++ /dev/null @@ -1,108 +0,0 @@ -From a6db97d2574d509b2077236ff48d70c3469a042e Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Sun, 20 Jan 2019 16:39:08 +0800 -Subject: [PATCH 069/111] pause: fix log pause/unpause event twice - -reason: fix pause/unpause log event twice - -Change-Id: If136d713afd37806256500d4760d0a344f7c5d92 -Signed-off-by: jingrui ---- - components/engine/daemon/monitor.go | 36 ++++++++++++++++++----------- - components/engine/daemon/pause.go | 7 ------ - components/engine/daemon/unpause.go | 6 ----- - 3 files changed, 22 insertions(+), 27 deletions(-) - -diff --git a/components/engine/daemon/monitor.go b/components/engine/daemon/monitor.go -index 807cdcaa89..51159eb76d 100644 ---- a/components/engine/daemon/monitor.go -+++ b/components/engine/daemon/monitor.go -@@ -167,28 +167,36 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerd.EventType, ei libc - c.Lock() - defer c.Unlock() - -- if !c.Paused { -- c.Paused = true -- daemon.setStateCounter(c) -- daemon.updateHealthMonitor(c) -- if err := c.CheckpointTo(daemon.containersReplica); err != nil { -- return err -+ if daemon.IsNativeRuntime(c.HostConfig.Runtime) { -+ logrus.Infof("Pause is moved to docker, skip.") -+ } else { -+ if !c.Paused { -+ c.Paused = true -+ daemon.setStateCounter(c) -+ daemon.updateHealthMonitor(c) -+ if err := c.CheckpointTo(daemon.containersReplica); err != nil { -+ return err -+ } -+ daemon.LogContainerEvent(c, "pause") - } -- daemon.LogContainerEvent(c, "pause") - } - case libcontainerd.EventResumed: - c.Lock() - defer c.Unlock() - -- if c.Paused { -- c.Paused = false -- daemon.setStateCounter(c) -- daemon.updateHealthMonitor(c) -+ if daemon.IsNativeRuntime(c.HostConfig.Runtime) { -+ logrus.Infof("Pause is moved to docker, skip.") -+ } else { -+ if c.Paused { -+ c.Paused = false -+ daemon.setStateCounter(c) -+ daemon.updateHealthMonitor(c) - -- if err := c.CheckpointTo(daemon.containersReplica); err != nil { -- return err -+ if err := c.CheckpointTo(daemon.containersReplica); err != nil { -+ return err -+ } -+ daemon.LogContainerEvent(c, "unpause") - } -- daemon.LogContainerEvent(c, "unpause") - } - } - return nil -diff --git a/components/engine/daemon/pause.go b/components/engine/daemon/pause.go -index 6f9d8b0f70..494aa326d9 100644 ---- a/components/engine/daemon/pause.go -+++ b/components/engine/daemon/pause.go -@@ -48,13 +48,6 @@ func (daemon *Daemon) containerPause(container *container.Container) error { - if err := freezer.Pause(); err != nil { - return fmt.Errorf("Cannot pause container %s: %v", container.ID, err) - } -- -- container.Paused = true -- daemon.setStateCounter(container) -- if err := container.CheckpointTo(daemon.containersReplica); err != nil { -- return err -- } -- daemon.LogContainerEvent(container, "pause") - } else { - if err := daemon.containerd.Pause(context.Background(), container.ID); err != nil { - return fmt.Errorf("Cannot pause container %s: %s", container.ID, err) -diff --git a/components/engine/daemon/unpause.go b/components/engine/daemon/unpause.go -index 2d3c056566..a75589b888 100644 ---- a/components/engine/daemon/unpause.go -+++ b/components/engine/daemon/unpause.go -@@ -41,12 +41,6 @@ func (daemon *Daemon) containerUnpause(container *container.Container) error { - if err := freezer.Resume(); err != nil { - return fmt.Errorf("Cannot unpause container %s: %s", container.ID, err) - } -- container.Paused = false -- daemon.setStateCounter(container) -- if err := container.CheckpointTo(daemon.containersReplica); err != nil { -- return err -- } -- daemon.LogContainerEvent(container, "unpause") - } else { - if err := daemon.containerd.Resume(context.Background(), container.ID); err != nil { - return fmt.Errorf("Cannot unpause container %s: %s", container.ID, err) --- -2.17.1 - diff --git a/patch/0070-test-fix-umask-make-syscall-test-failed.patch b/patch/0070-test-fix-umask-make-syscall-test-failed.patch deleted file mode 100644 index dbc260c..0000000 --- a/patch/0070-test-fix-umask-make-syscall-test-failed.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 1bb39edbf403bf31aaece61510b43d9a6e781f7d Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Mon, 21 Jan 2019 17:57:03 +0800 -Subject: [PATCH 070/111] test: fix umask make syscall-test failed - -reason: set umask 0022 make sure add file's mode to image syscall-test -as exepected, so user has permission to exec. - -Change-Id: Iaad1bc328c81b77aa630bcb9f974aeee3a50ecbf -Signed-off-by: jingrui ---- - .../engine/integration-cli/fixtures_linux_daemon_test.go | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/components/engine/integration-cli/fixtures_linux_daemon_test.go b/components/engine/integration-cli/fixtures_linux_daemon_test.go -index 2387a9ebee..7be3c8b185 100644 ---- a/components/engine/integration-cli/fixtures_linux_daemon_test.go -+++ b/components/engine/integration-cli/fixtures_linux_daemon_test.go -@@ -9,6 +9,7 @@ import ( - "runtime" - "strings" - "sync" -+ "syscall" - - "github.com/docker/docker/integration-cli/checker" - "github.com/docker/docker/internal/test/fixtures/load" -@@ -28,6 +29,9 @@ var ensureSyscallTestOnce sync.Once - - func ensureSyscallTest(c *check.C) { - var doIt bool -+ mask := syscall.Umask(0022) -+ defer syscall.Umask(mask) -+ - ensureSyscallTestOnce.Do(func() { - doIt = true - }) --- -2.17.1 - diff --git a/patch/0071-devmapper-Increace-udev-wait-timeout-to-185s.patch b/patch/0071-devmapper-Increace-udev-wait-timeout-to-185s.patch deleted file mode 100644 index 73b8c61..0000000 --- a/patch/0071-devmapper-Increace-udev-wait-timeout-to-185s.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 6a40d11a3bc9be18cb50fb86099ff52a6d459335 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Mon, 21 Jan 2019 18:57:43 +0800 -Subject: [PATCH 071/111] devmapper: Increace udev wait timeout to - 185s - -reason: cherry-pick commits to docker-18.09 - -cherry-pick e89615bd40c32f95d095c17efaf5258b15543080 from docker-1.11.2 - - The default time out of latest systemd-udevd on RTOS and EulerOS - is 180s, we use 185s. Even if the time out of systemd-udevd is 30s, - set 185s on docker side is also safe, it will just take a longer time - to return when time out really happen, we should make sure the timeout - on docker side is bigger than the timeout on systemd-udevd. - - Signed-off-by: Lei Jitang - -Change-Id: I05d722f22a0c7728ae1bbe23ab67c567d1694b67 -Signed-off-by: jingrui ---- - components/engine/daemon/graphdriver/devmapper/deviceset.go | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/components/engine/daemon/graphdriver/devmapper/deviceset.go b/components/engine/daemon/graphdriver/devmapper/deviceset.go -index f4dc589c6e..f5c0b044c4 100644 ---- a/components/engine/daemon/graphdriver/devmapper/deviceset.go -+++ b/components/engine/daemon/graphdriver/devmapper/deviceset.go -@@ -42,9 +42,9 @@ var ( - defaultUdevSyncOverride = false - maxDeviceID = 0xffffff // 24 bit, pool limit - deviceIDMapSz = (maxDeviceID + 1) / 8 -- // The default timeout is 30s from `man systemd-udevd`, we use 35 -- // just to make sure the timeout really happened in systemd-udevd -- defaultUdevWaitTimeout = 35 -+ // The default timeout for latest systemd on RTOS and EulerOS is 180s -+ // we use 185s to make sure the timeout really happened. -+ defaultUdevWaitTimeout = 185 - driverDeferredRemovalSupport = false - enableDeferredRemoval = false - enableDeferredDeletion = false --- -2.17.1 - diff --git a/patch/0072-pause-fix-test-can-not-stop-paused-container-.patch b/patch/0072-pause-fix-test-can-not-stop-paused-container-.patch deleted file mode 100644 index 98a518a..0000000 --- a/patch/0072-pause-fix-test-can-not-stop-paused-container-.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 59d4dd7fdb0c33dc4c3be2330606ec7724cb368c Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Fri, 11 Jan 2019 17:16:21 +0800 -Subject: [PATCH 072/111] pause: fix test can not stop paused - container failed - -reason: pause function moved to docker and does not support stop paused -container. return error message when stop a paused container. - -Change-Id: Ia7b15877980088cdb4eaf9f7e3dd86667df0157b -Signed-off-by: jingrui ---- - components/engine/integration/container/pause_test.go | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/components/engine/integration/container/pause_test.go b/components/engine/integration/container/pause_test.go -index 8dd2d784b7..da274c89ce 100644 ---- a/components/engine/integration/container/pause_test.go -+++ b/components/engine/integration/container/pause_test.go -@@ -79,9 +79,10 @@ func TestPauseStopPausedContainer(t *testing.T) { - assert.NilError(t, err) - - err = client.ContainerStop(ctx, cID, nil) -- assert.NilError(t, err) -- -- poll.WaitOn(t, container.IsStopped(ctx, client, cID), poll.WithDelay(100*time.Millisecond)) -+ // assert.NilError(t, err) -+ // poll.WaitOn(t, container.IsStopped(ctx, client, cID), poll.WithDelay(100*time.Millisecond)) -+ assert.Check(t, is.ErrorContains(err, "is paused")) -+ client.ContainerUnpause(ctx, cID) - } - - func getEventActions(t *testing.T, messages <-chan events.Message, errs <-chan error) []string { --- -2.17.1 - diff --git a/patch/0073-service-update-docker.service-with-old-revisi.patch b/patch/0073-service-update-docker.service-with-old-revisi.patch deleted file mode 100644 index 8c3831f..0000000 --- a/patch/0073-service-update-docker.service-with-old-revisi.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 67f1bfcb1df53fcfc044927eda37f0f8b45498dc Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Mon, 21 Jan 2019 22:25:42 +0800 -Subject: [PATCH 073/111] service: update docker.service with old - revision - -reason: use docker.service as the same one used in Euleros docker -1.11.2 and 17.06 - -Change-Id: I3deb3f3a24d837c98e535550545fd49ea0822629 -Signed-off-by: lujingxiao ---- - .../contrib/init/systemd/docker.service | 28 ++++++++----------- - 1 file changed, 11 insertions(+), 17 deletions(-) - -diff --git a/components/engine/contrib/init/systemd/docker.service b/components/engine/contrib/init/systemd/docker.service -index 517463172b..26c0fe648b 100644 ---- a/components/engine/contrib/init/systemd/docker.service -+++ b/components/engine/contrib/init/systemd/docker.service -@@ -1,34 +1,28 @@ - [Unit] - Description=Docker Application Container Engine - Documentation=https://docs.docker.com --After=network-online.target docker.socket firewalld.service -+After=network-online.target firewalld.service - Wants=network-online.target --Requires=docker.socket - - [Service] - Type=notify --# the default is not to use systemd for cgroups because the delegate issues still --# exists and systemd currently does not support the cgroup feature set required --# for containers run by docker --ExecStart=/usr/bin/dockerd -H fd:// -+EnvironmentFile=-/etc/sysconfig/docker -+EnvironmentFile=-/etc/sysconfig/docker-storage -+EnvironmentFile=-/etc/sysconfig/docker-network -+Environment=GOTRACEBACK=crash -+ -+ExecStart=/usr/bin/dockerd $OPTIONS \ -+ $DOCKER_STORAGE_OPTIONS \ -+ $DOCKER_NETWORK_OPTIONS \ -+ $INSECURE_REGISTRY - ExecReload=/bin/kill -s HUP $MAINPID - LimitNOFILE=1048576 --# Having non-zero Limit*s causes performance problems due to accounting overhead --# in the kernel. We recommend using cgroups to do container-local accounting. --LimitNPROC=infinity -+LimitNPROC=1048576 - LimitCORE=infinity --# Uncomment TasksMax if your systemd version supports it. --# Only systemd 226 and above support this version. --#TasksMax=infinity --TimeoutStartSec=0 - # set delegate yes so that systemd does not reset the cgroups of docker containers - Delegate=yes - # kill only the docker process, not all processes in the cgroup - KillMode=process --# restart the docker process if it exits prematurely --Restart=on-failure --StartLimitBurst=3 --StartLimitInterval=60s - - [Install] - WantedBy=multi-user.target --- -2.17.1 - diff --git a/patch/0076-version-add-EulerVersion.patch b/patch/0076-version-add-EulerVersion.patch deleted file mode 100644 index 253544b..0000000 --- a/patch/0076-version-add-EulerVersion.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 22f9a89d9ddcb03aa5b00dc9ad4372f776c5f73b Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Mon, 21 Jan 2019 23:05:47 +0800 -Subject: [PATCH 076/111] version: add EulerVersion - -reason: Add EulerVersion and update-version.sh - -Cherry-pick from 17.06 for -- 030513895 Add EulerVersion -- 102ee9ddc docker-17: add update-version tool for obs build - -Change-Id: I95c9b98bd35e243ce1074fa7dd0d477bdf7dcee9 -Signed-off-by: Lei Jitang -Signed-off-by: lujingxiao ---- - components/cli/cli/command/system/version.go | 4 ++++ - components/cli/cli/version.go | 1 + - components/cli/docker.Makefile | 3 ++- - components/cli/scripts/build/.variables | 2 ++ - .../github.com/docker/docker/api/types/types.go | 1 + - components/engine/api/types/types.go | 1 + - components/engine/daemon/info.go | 3 ++- - components/engine/dockerversion/version_lib.go | 1 + - components/engine/hack/make.sh | 1 + - components/engine/hack/make/.go-autogen | 1 + - 13 files changed, 34 insertions(+), 2 deletions(-) - -diff --git a/components/cli/cli/command/system/version.go b/components/cli/cli/command/system/version.go -index 7593b11b81..c13d135ae4 100644 ---- a/components/cli/cli/command/system/version.go -+++ b/components/cli/cli/command/system/version.go -@@ -23,6 +23,7 @@ import ( - var versionTemplate = `{{with .Client -}} - Client:{{if ne .Platform.Name ""}} {{.Platform.Name}}{{end}} - Version: {{.Version}} -+ EulerVersion: {{.EulerVersion}} - API version: {{.APIVersion}}{{if ne .APIVersion .DefaultAPIVersion}} (downgraded from {{.DefaultAPIVersion}}){{end}} - Go version: {{.GoVersion}} - Git commit: {{.GitCommit}} -@@ -38,6 +39,7 @@ Server:{{if ne .Platform.Name ""}} {{.Platform.Name}}{{end}} - {{$component.Name}}: - {{- if eq $component.Name "Engine" }} - Version: {{.Version}} -+ EulerVersion: {{index .Details "EulerVersion"}} - API version: {{index .Details "ApiVersion"}} (minimum version {{index .Details "MinAPIVersion"}}) - Go version: {{index .Details "GoVersion"}} - Git commit: {{index .Details "GitCommit"}} -@@ -69,6 +71,7 @@ type clientVersion struct { - Platform struct{ Name string } `json:",omitempty"` - - Version string -+ EulerVersion string - APIVersion string `json:"ApiVersion"` - DefaultAPIVersion string `json:"DefaultAPIVersion,omitempty"` - GitCommit string -@@ -135,6 +138,7 @@ func runVersion(dockerCli command.Cli, opts *versionOptions) error { - Client: clientVersion{ - Platform: struct{ Name string }{cli.PlatformName}, - Version: cli.Version, -+ EulerVersion: cli.EulerVersion, - APIVersion: dockerCli.Client().ClientVersion(), - DefaultAPIVersion: dockerCli.DefaultVersion(), - GoVersion: runtime.Version(), -diff --git a/components/cli/cli/version.go b/components/cli/cli/version.go -index c4120b9585..eeab90cad2 100644 ---- a/components/cli/cli/version.go -+++ b/components/cli/cli/version.go -@@ -5,6 +5,7 @@ package cli - var ( - PlatformName = "" - Version = "unknown-version" -+ EulerVersion = "unkonwn-version" - GitCommit = "unknown-commit" - BuildTime = "unknown-buildtime" - ) -diff --git a/components/cli/docker.Makefile b/components/cli/docker.Makefile -index 28819997bc..3284d8ce0a 100644 ---- a/components/cli/docker.Makefile -+++ b/components/cli/docker.Makefile -@@ -12,7 +12,8 @@ VALIDATE_IMAGE_NAME = docker-cli-shell-validate$(IMAGE_TAG) - E2E_IMAGE_NAME = docker-cli-e2e$(IMAGE_TAG) - MOUNTS = -v "$(CURDIR)":/go/src/github.com/docker/cli - VERSION = $(shell cat VERSION) --ENVVARS = -e VERSION=$(VERSION) -e GITCOMMIT -e PLATFORM -+GITCOMMIT = $(shell git rev-parse --short HEAD 2> /dev/null || true) -+ENVVARS = -e VERSION=$(VERSION) -e GITCOMMIT=$(GITCOMMIT) -e PLATFORM - - # build docker image (dockerfiles/Dockerfile.build) - .PHONY: build_docker_image -diff --git a/components/cli/scripts/build/.variables b/components/cli/scripts/build/.variables -index 208f44c316..d50403266e 100755 ---- a/components/cli/scripts/build/.variables -+++ b/components/cli/scripts/build/.variables -@@ -3,6 +3,7 @@ set -eu - - PLATFORM=${PLATFORM:-} - VERSION=${VERSION:-"unknown-version"} -+EULERVERSION=${EULERVERSION:-$(cat VERSION-EULER)} - GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)} - BUILDTIME=${BUILDTIME:-$(date --utc --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/')} - -@@ -17,6 +18,7 @@ export LDFLAGS="\ - -X \"github.com/docker/cli/cli.GitCommit=${GITCOMMIT}\" \ - -X \"github.com/docker/cli/cli.BuildTime=${BUILDTIME}\" \ - -X \"github.com/docker/cli/cli.Version=${VERSION}\" \ -+ -X \"github.com/docker/cli/cli.EulerVersion=${EULERVERSION}\" \ - ${LDFLAGS:-} \ - " - -diff --git a/components/cli/vendor/github.com/docker/docker/api/types/types.go b/components/cli/vendor/github.com/docker/docker/api/types/types.go -index 2fb6c5478b..56f556cad7 100644 ---- a/components/cli/vendor/github.com/docker/docker/api/types/types.go -+++ b/components/cli/vendor/github.com/docker/docker/api/types/types.go -@@ -124,6 +124,7 @@ type Version struct { - // The following fields are deprecated, they relate to the Engine component and are kept for backwards compatibility - - Version string -+ EulerVersion string - APIVersion string `json:"ApiVersion"` - MinAPIVersion string `json:"MinAPIVersion,omitempty"` - GitCommit string -diff --git a/components/engine/api/types/types.go b/components/engine/api/types/types.go -index 820d513cbb..78e97daf98 100644 ---- a/components/engine/api/types/types.go -+++ b/components/engine/api/types/types.go -@@ -125,6 +125,7 @@ type Version struct { - // The following fields are deprecated, they relate to the Engine component and are kept for backwards compatibility - - Version string -+ EulerVersion string - APIVersion string `json:"ApiVersion"` - MinAPIVersion string `json:"MinAPIVersion,omitempty"` - GitCommit string -diff --git a/components/engine/daemon/info.go b/components/engine/daemon/info.go -index 523a396643..4acad11b70 100644 ---- a/components/engine/daemon/info.go -+++ b/components/engine/daemon/info.go -@@ -85,13 +85,13 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) { - // SystemVersion returns version information about the daemon. - func (daemon *Daemon) SystemVersion() types.Version { - kernelVersion := kernelVersion() -- - v := types.Version{ - Components: []types.ComponentVersion{ - { - Name: "Engine", - Version: dockerversion.Version, - Details: map[string]string{ -+ "EulerVersion": dockerversion.EulerVersion, - "GitCommit": dockerversion.GitCommit, - "ApiVersion": api.DefaultVersion, - "MinAPIVersion": api.MinVersion, -@@ -107,6 +107,7 @@ func (daemon *Daemon) SystemVersion() types.Version { - - // Populate deprecated fields for older clients - Version: dockerversion.Version, -+ EulerVersion: dockerversion.EulerVersion, - GitCommit: dockerversion.GitCommit, - APIVersion: api.DefaultVersion, - MinAPIVersion: api.MinVersion, -diff --git a/components/engine/dockerversion/version_lib.go b/components/engine/dockerversion/version_lib.go -index 5d9b3fdd2b..84b1339b5b 100644 ---- a/components/engine/dockerversion/version_lib.go -+++ b/components/engine/dockerversion/version_lib.go -@@ -8,6 +8,7 @@ package dockerversion // import "github.com/docker/docker/dockerversion" - const ( - GitCommit = "library-import" - Version = "library-import" -+ EulerVersion = "library-import" - BuildTime = "library-import" - IAmStatic = "library-import" - InitCommitID = "library-import" -diff --git a/components/engine/hack/make.sh b/components/engine/hack/make.sh -index 2f4ece3cdb..fa87d9110f 100755 ---- a/components/engine/hack/make.sh -+++ b/components/engine/hack/make.sh -@@ -65,6 +65,7 @@ DEFAULT_BUNDLES=( - cross - ) - -+VERSION_EULER=$(< ./VERSION-EULER) - VERSION=${VERSION:-dev} - ! BUILDTIME=$(date -u -d "@${SOURCE_DATE_EPOCH:-$(date +%s)}" --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/') - if [ "$DOCKER_GITCOMMIT" ]; then -diff --git a/components/engine/hack/make/.go-autogen b/components/engine/hack/make/.go-autogen -index ea8a32ff5d..99d45e9cb8 100644 ---- a/components/engine/hack/make/.go-autogen -+++ b/components/engine/hack/make/.go-autogen -@@ -17,6 +17,7 @@ package dockerversion - const ( - GitCommit string = "$GITCOMMIT" - Version string = "$VERSION" -+ EulerVersion string = "$VERSION_EULER" - BuildTime string = "$BUILDTIME" - IAmStatic string = "${IAMSTATIC:-true}" - PlatformName string = "${PLATFORM}" --- -2.17.1 - diff --git a/patch/0077-image-fix-file-not-exist-for-check-file-size.patch b/patch/0077-image-fix-file-not-exist-for-check-file-size.patch deleted file mode 100644 index eb6c3f1..0000000 --- a/patch/0077-image-fix-file-not-exist-for-check-file-size.patch +++ /dev/null @@ -1,32 +0,0 @@ -From be262686615a41b7377e5e19c9aae2a1d71cb4fb Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Tue, 22 Jan 2019 17:20:38 +0800 -Subject: [PATCH 077/111] image: fix file not exist for check file - size - -reason: check file size should support file not exist. - -Change-Id: Iae3b8d4f477d6cfc51ba71a185a598687f8393a2 -Signed-off-by: jingrui ---- - components/engine/image/tarexport/load.go | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/components/engine/image/tarexport/load.go b/components/engine/image/tarexport/load.go -index b9f8f7e3ac..34574129f1 100644 ---- a/components/engine/image/tarexport/load.go -+++ b/components/engine/image/tarexport/load.go -@@ -432,6 +432,10 @@ func checkValidParent(img, parent *image.Image) bool { - func checkJsonFileSize(path string) error { - fileInfo, err := os.Stat(path) - if err != nil { -+ // path can not exist. -+ if os.IsNotExist(err) { -+ return nil -+ } - return err - } - fileSize := fileInfo.Size() --- -2.17.1 - diff --git a/patch/0078-spec-add-missing-sysconfigs-to-rpm.patch b/patch/0078-spec-add-missing-sysconfigs-to-rpm.patch deleted file mode 100644 index eb4a38c..0000000 --- a/patch/0078-spec-add-missing-sysconfigs-to-rpm.patch +++ /dev/null @@ -1,53 +0,0 @@ -From bcd276b5b62e1b5ff46eadad71417de076797ec8 Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Tue, 22 Jan 2019 17:26:35 +0800 -Subject: [PATCH 078/111] spec: add missing sysconfigs to rpm - -reason: add missing sysconfigs to rpm, including -- /etc/sysconfig/docker -- /etc/sysconfig/docker-network -- /etc/sysconfig/docker-storage - -Partly cherry-pick from 17.06 780e079a - -Change-Id: I7a31bc6d99bab6c6a7a60988bc66db2d48f6ca4b -Signed-off-by: Lei Jitang -Signed-off-by: lujingxiao ---- - .../contrib/init/sysvinit-redhat/docker-network | 2 ++ - .../contrib/init/sysvinit-redhat/docker-storage | 14 ++++++++++++++ - 5 files changed, 27 insertions(+), 4 deletions(-) - create mode 100644 components/engine/contrib/init/sysvinit-redhat/docker-network - create mode 100644 components/engine/contrib/init/sysvinit-redhat/docker-storage - -diff --git a/components/engine/contrib/init/sysvinit-redhat/docker-network b/components/engine/contrib/init/sysvinit-redhat/docker-network -new file mode 100644 -index 0000000000..048d1582ec ---- /dev/null -+++ b/components/engine/contrib/init/sysvinit-redhat/docker-network -@@ -0,0 +1,2 @@ -+# /etc/sysconfig/docker-network -+DOCKER_NETWORK_OPTIONS= -diff --git a/components/engine/contrib/init/sysvinit-redhat/docker-storage b/components/engine/contrib/init/sysvinit-redhat/docker-storage -new file mode 100644 -index 0000000000..3dc16542ff ---- /dev/null -+++ b/components/engine/contrib/init/sysvinit-redhat/docker-storage -@@ -0,0 +1,14 @@ -+# This file may be automatically generated by an installation program. -+ -+# By default, Docker uses a loopback-mounted sparse file in -+# /var/lib/docker. The loopback makes it slower, and there are some -+# restrictive defaults, such as 100GB max storage. -+ -+# If your installation did not set a custom storage for Docker, you -+# may do it below. -+ -+# Example: Use a custom pair of raw logical volumes (one for metadata, -+# one for data). -+# DOCKER_STORAGE_OPTIONS = --storage-opt dm.metadatadev=/dev/mylogvol/my-docker-metadata --storage-opt dm.datadev=/dev/mylogvol/my-docker-data -+ -+DOCKER_STORAGE_OPTIONS= --- -2.17.1 - diff --git a/patch/0079-rwlayer-fix-deadlock-for-docker-commit-export.patch b/patch/0079-rwlayer-fix-deadlock-for-docker-commit-export.patch deleted file mode 100644 index 7612c00..0000000 --- a/patch/0079-rwlayer-fix-deadlock-for-docker-commit-export.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 1564b7d772b69da0ba7f6814af2fc094def9d2fd Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 23 Jan 2019 11:07:12 +0800 -Subject: [PATCH 079/111] rwlayer: fix deadlock for docker - commit/export - -reason: this commit avoid deadlock while del reference count. - -Change-Id: I2627752ed38c7bb9d789f4604acd43d130bcb926 -Signed-off-by: jingrui ---- - components/engine/layer/layer_store.go | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/components/engine/layer/layer_store.go b/components/engine/layer/layer_store.go -index cbb1ee4a19..553b098dfd 100644 ---- a/components/engine/layer/layer_store.go -+++ b/components/engine/layer/layer_store.go -@@ -680,8 +680,6 @@ func (ls *layerStore) ReleaseRWLayer(l RWLayer) ([]Metadata, error) { - return []Metadata{}, nil - } - -- m.Lock() -- defer m.Unlock() - if err := m.deleteReference(l); err != nil { - return nil, err - } -@@ -690,6 +688,8 @@ func (ls *layerStore) ReleaseRWLayer(l RWLayer) ([]Metadata, error) { - return []Metadata{}, nil - } - -+ m.Lock() -+ defer m.Unlock() - if err := ls.driver.Remove(m.mountID); err != nil { - logrus.Errorf("Error removing mounted layer %s: %s", m.name, err) - m.retakeReference(l) --- -2.17.1 - diff --git a/patch/0080-selinux-Add-selinux-policy-for-docker.patch b/patch/0080-selinux-Add-selinux-policy-for-docker.patch deleted file mode 100644 index 1e7ece3..0000000 --- a/patch/0080-selinux-Add-selinux-policy-for-docker.patch +++ /dev/null @@ -1,1439 +0,0 @@ -From 35e53a45a4faa11b6acf33ee2ee0f58a6b2fb39c Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Wed, 23 Jan 2019 15:16:09 +0800 -Subject: [PATCH 080/111] selinux: Add selinux policy for docker - -reason: Add selinux policy for docker - -Change-Id: Ife0dd569a89df301ae3496454e1c326b8a663818 -Signed-off-by: Shukui Yang -Signed-off-by: lujingxiao ---- - .../docker-engine-selinux/LICENSE | 339 +++++++++++++ - .../docker-engine-selinux/Makefile | 23 + - .../docker-engine-selinux/README.md | 1 + - .../docker-engine-selinux/docker.fc | 20 + - .../docker-engine-selinux/docker.if | 461 ++++++++++++++++++ - .../docker-engine-selinux/docker.te | 414 ++++++++++++++++ - .../docker-engine-selinux-euleros.spec | 109 +++++ - 10 files changed, 1371 insertions(+), 4 deletions(-) - create mode 100644 components/engine/contrib/selinux-euleros/docker-engine-selinux/LICENSE - create mode 100644 components/engine/contrib/selinux-euleros/docker-engine-selinux/Makefile - create mode 100644 components/engine/contrib/selinux-euleros/docker-engine-selinux/README.md - create mode 100644 components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.fc - create mode 100644 components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.if - create mode 100644 components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.te - create mode 100644 components/engine/hack/make/.build-rpm/docker-engine-selinux-euleros.spec - -diff --git a/components/engine/contrib/selinux-euleros/docker-engine-selinux/LICENSE b/components/engine/contrib/selinux-euleros/docker-engine-selinux/LICENSE -new file mode 100644 -index 0000000000..d511905c16 ---- /dev/null -+++ b/components/engine/contrib/selinux-euleros/docker-engine-selinux/LICENSE -@@ -0,0 +1,339 @@ -+ GNU GENERAL PUBLIC LICENSE -+ Version 2, June 1991 -+ -+ Copyright (C) 1989, 1991 Free Software Foundation, Inc., -+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ Everyone is permitted to copy and distribute verbatim copies -+ of this license document, but changing it is not allowed. -+ -+ Preamble -+ -+ The licenses for most software are designed to take away your -+freedom to share and change it. By contrast, the GNU General Public -+License is intended to guarantee your freedom to share and change free -+software--to make sure the software is free for all its users. This -+General Public License applies to most of the Free Software -+Foundation's software and to any other program whose authors commit to -+using it. (Some other Free Software Foundation software is covered by -+the GNU Lesser General Public License instead.) You can apply it to -+your programs, too. -+ -+ When we speak of free software, we are referring to freedom, not -+price. Our General Public Licenses are designed to make sure that you -+have the freedom to distribute copies of free software (and charge for -+this service if you wish), that you receive source code or can get it -+if you want it, that you can change the software or use pieces of it -+in new free programs; and that you know you can do these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+anyone to deny you these rights or to ask you to surrender the rights. -+These restrictions translate to certain responsibilities for you if you -+distribute copies of the software, or if you modify it. -+ -+ For example, if you distribute copies of such a program, whether -+gratis or for a fee, you must give the recipients all the rights that -+you have. You must make sure that they, too, receive or can get the -+source code. And you must show them these terms so they know their -+rights. -+ -+ We protect your rights with two steps: (1) copyright the software, and -+(2) offer you this license which gives you legal permission to copy, -+distribute and/or modify the software. -+ -+ Also, for each author's protection and ours, we want to make certain -+that everyone understands that there is no warranty for this free -+software. If the software is modified by someone else and passed on, we -+want its recipients to know that what they have is not the original, so -+that any problems introduced by others will not reflect on the original -+authors' reputations. -+ -+ Finally, any free program is threatened constantly by software -+patents. We wish to avoid the danger that redistributors of a free -+program will individually obtain patent licenses, in effect making the -+program proprietary. To prevent this, we have made it clear that any -+patent must be licensed for everyone's free use or not licensed at all. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. -+ -+ GNU GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License applies to any program or other work which contains -+a notice placed by the copyright holder saying it may be distributed -+under the terms of this General Public License. The "Program", below, -+refers to any such program or work, and a "work based on the Program" -+means either the Program or any derivative work under copyright law: -+that is to say, a work containing the Program or a portion of it, -+either verbatim or with modifications and/or translated into another -+language. (Hereinafter, translation is included without limitation in -+the term "modification".) Each licensee is addressed as "you". -+ -+Activities other than copying, distribution and modification are not -+covered by this License; they are outside its scope. The act of -+running the Program is not restricted, and the output from the Program -+is covered only if its contents constitute a work based on the -+Program (independent of having been made by running the Program). -+Whether that is true depends on what the Program does. -+ -+ 1. You may copy and distribute verbatim copies of the Program's -+source code as you receive it, in any medium, provided that you -+conspicuously and appropriately publish on each copy an appropriate -+copyright notice and disclaimer of warranty; keep intact all the -+notices that refer to this License and to the absence of any warranty; -+and give any other recipients of the Program a copy of this License -+along with the Program. -+ -+You may charge a fee for the physical act of transferring a copy, and -+you may at your option offer warranty protection in exchange for a fee. -+ -+ 2. You may modify your copy or copies of the Program or any portion -+of it, thus forming a work based on the Program, and copy and -+distribute such modifications or work under the terms of Section 1 -+above, provided that you also meet all of these conditions: -+ -+ a) You must cause the modified files to carry prominent notices -+ stating that you changed the files and the date of any change. -+ -+ b) You must cause any work that you distribute or publish, that in -+ whole or in part contains or is derived from the Program or any -+ part thereof, to be licensed as a whole at no charge to all third -+ parties under the terms of this License. -+ -+ c) If the modified program normally reads commands interactively -+ when run, you must cause it, when started running for such -+ interactive use in the most ordinary way, to print or display an -+ announcement including an appropriate copyright notice and a -+ notice that there is no warranty (or else, saying that you provide -+ a warranty) and that users may redistribute the program under -+ these conditions, and telling the user how to view a copy of this -+ License. (Exception: if the Program itself is interactive but -+ does not normally print such an announcement, your work based on -+ the Program is not required to print an announcement.) -+ -+These requirements apply to the modified work as a whole. If -+identifiable sections of that work are not derived from the Program, -+and can be reasonably considered independent and separate works in -+themselves, then this License, and its terms, do not apply to those -+sections when you distribute them as separate works. But when you -+distribute the same sections as part of a whole which is a work based -+on the Program, the distribution of the whole must be on the terms of -+this License, whose permissions for other licensees extend to the -+entire whole, and thus to each and every part regardless of who wrote it. -+ -+Thus, it is not the intent of this section to claim rights or contest -+your rights to work written entirely by you; rather, the intent is to -+exercise the right to control the distribution of derivative or -+collective works based on the Program. -+ -+In addition, mere aggregation of another work not based on the Program -+with the Program (or with a work based on the Program) on a volume of -+a storage or distribution medium does not bring the other work under -+the scope of this License. -+ -+ 3. You may copy and distribute the Program (or a work based on it, -+under Section 2) in object code or executable form under the terms of -+Sections 1 and 2 above provided that you also do one of the following: -+ -+ a) Accompany it with the complete corresponding machine-readable -+ source code, which must be distributed under the terms of Sections -+ 1 and 2 above on a medium customarily used for software interchange; or, -+ -+ b) Accompany it with a written offer, valid for at least three -+ years, to give any third party, for a charge no more than your -+ cost of physically performing source distribution, a complete -+ machine-readable copy of the corresponding source code, to be -+ distributed under the terms of Sections 1 and 2 above on a medium -+ customarily used for software interchange; or, -+ -+ c) Accompany it with the information you received as to the offer -+ to distribute corresponding source code. (This alternative is -+ allowed only for noncommercial distribution and only if you -+ received the program in object code or executable form with such -+ an offer, in accord with Subsection b above.) -+ -+The source code for a work means the preferred form of the work for -+making modifications to it. For an executable work, complete source -+code means all the source code for all modules it contains, plus any -+associated interface definition files, plus the scripts used to -+control compilation and installation of the executable. However, as a -+special exception, the source code distributed need not include -+anything that is normally distributed (in either source or binary -+form) with the major components (compiler, kernel, and so on) of the -+operating system on which the executable runs, unless that component -+itself accompanies the executable. -+ -+If distribution of executable or object code is made by offering -+access to copy from a designated place, then offering equivalent -+access to copy the source code from the same place counts as -+distribution of the source code, even though third parties are not -+compelled to copy the source along with the object code. -+ -+ 4. You may not copy, modify, sublicense, or distribute the Program -+except as expressly provided under this License. Any attempt -+otherwise to copy, modify, sublicense or distribute the Program is -+void, and will automatically terminate your rights under this License. -+However, parties who have received copies, or rights, from you under -+this License will not have their licenses terminated so long as such -+parties remain in full compliance. -+ -+ 5. You are not required to accept this License, since you have not -+signed it. However, nothing else grants you permission to modify or -+distribute the Program or its derivative works. These actions are -+prohibited by law if you do not accept this License. Therefore, by -+modifying or distributing the Program (or any work based on the -+Program), you indicate your acceptance of this License to do so, and -+all its terms and conditions for copying, distributing or modifying -+the Program or works based on it. -+ -+ 6. Each time you redistribute the Program (or any work based on the -+Program), the recipient automatically receives a license from the -+original licensor to copy, distribute or modify the Program subject to -+these terms and conditions. You may not impose any further -+restrictions on the recipients' exercise of the rights granted herein. -+You are not responsible for enforcing compliance by third parties to -+this License. -+ -+ 7. If, as a consequence of a court judgment or allegation of patent -+infringement or for any other reason (not limited to patent issues), -+conditions are imposed on you (whether by court order, agreement or -+otherwise) that contradict the conditions of this License, they do not -+excuse you from the conditions of this License. If you cannot -+distribute so as to satisfy simultaneously your obligations under this -+License and any other pertinent obligations, then as a consequence you -+may not distribute the Program at all. For example, if a patent -+license would not permit royalty-free redistribution of the Program by -+all those who receive copies directly or indirectly through you, then -+the only way you could satisfy both it and this License would be to -+refrain entirely from distribution of the Program. -+ -+If any portion of this section is held invalid or unenforceable under -+any particular circumstance, the balance of the section is intended to -+apply and the section as a whole is intended to apply in other -+circumstances. -+ -+It is not the purpose of this section to induce you to infringe any -+patents or other property right claims or to contest validity of any -+such claims; this section has the sole purpose of protecting the -+integrity of the free software distribution system, which is -+implemented by public license practices. Many people have made -+generous contributions to the wide range of software distributed -+through that system in reliance on consistent application of that -+system; it is up to the author/donor to decide if he or she is willing -+to distribute software through any other system and a licensee cannot -+impose that choice. -+ -+This section is intended to make thoroughly clear what is believed to -+be a consequence of the rest of this License. -+ -+ 8. If the distribution and/or use of the Program is restricted in -+certain countries either by patents or by copyrighted interfaces, the -+original copyright holder who places the Program under this License -+may add an explicit geographical distribution limitation excluding -+those countries, so that distribution is permitted only in or among -+countries not thus excluded. In such case, this License incorporates -+the limitation as if written in the body of this License. -+ -+ 9. The Free Software Foundation may publish revised and/or new versions -+of the General Public License from time to time. Such new versions will -+be similar in spirit to the present version, but may differ in detail to -+address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Program -+specifies a version number of this License which applies to it and "any -+later version", you have the option of following the terms and conditions -+either of that version or of any later version published by the Free -+Software Foundation. If the Program does not specify a version number of -+this License, you may choose any version ever published by the Free Software -+Foundation. -+ -+ 10. If you wish to incorporate parts of the Program into other free -+programs whose distribution conditions are different, write to the author -+to ask for permission. For software which is copyrighted by the Free -+Software Foundation, write to the Free Software Foundation; we sometimes -+make exceptions for this. Our decision will be guided by the two goals -+of preserving the free status of all derivatives of our free software and -+of promoting the sharing and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -+REPAIR OR CORRECTION. -+ -+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -+POSSIBILITY OF SUCH DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -+ -+ How to Apply These Terms to Your New Programs -+ -+ If you develop a new program, and you want it to be of the greatest -+possible use to the public, the best way to achieve this is to make it -+free software which everyone can redistribute and change under these terms. -+ -+ To do so, attach the following notices to the program. It is safest -+to attach them to the start of each source file to most effectively -+convey the exclusion of warranty; and each file should have at least -+the "copyright" line and a pointer to where the full notice is found. -+ -+ -+ Copyright (C) -+ -+ 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 -+ the Free Software Foundation; either version 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License along -+ with this program; if not, write to the Free Software Foundation, Inc., -+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ -+Also add information on how to contact you by electronic and paper mail. -+ -+If the program is interactive, make it output a short notice like this -+when it starts in an interactive mode: -+ -+ Gnomovision version 69, Copyright (C) year name of author -+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. -+ This is free software, and you are welcome to redistribute it -+ under certain conditions; type `show c' for details. -+ -+The hypothetical commands `show w' and `show c' should show the appropriate -+parts of the General Public License. Of course, the commands you use may -+be called something other than `show w' and `show c'; they could even be -+mouse-clicks or menu items--whatever suits your program. -+ -+You should also get your employer (if you work as a programmer) or your -+school, if any, to sign a "copyright disclaimer" for the program, if -+necessary. Here is a sample; alter the names: -+ -+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program -+ `Gnomovision' (which makes passes at compilers) written by James Hacker. -+ -+ , 1 April 1989 -+ Ty Coon, President of Vice -+ -+This General Public License does not permit incorporating your program into -+proprietary programs. If your program is a subroutine library, you may -+consider it more useful to permit linking proprietary applications with the -+library. If this is what you want to do, use the GNU Lesser General -+Public License instead of this License. -diff --git a/components/engine/contrib/selinux-euleros/docker-engine-selinux/Makefile b/components/engine/contrib/selinux-euleros/docker-engine-selinux/Makefile -new file mode 100644 -index 0000000000..16df33ef32 ---- /dev/null -+++ b/components/engine/contrib/selinux-euleros/docker-engine-selinux/Makefile -@@ -0,0 +1,23 @@ -+TARGETS?=docker -+MODULES?=${TARGETS:=.pp.bz2} -+SHAREDIR?=/usr/share -+ -+all: ${TARGETS:=.pp.bz2} -+ -+%.pp.bz2: %.pp -+ @echo Compressing $^ -\> $@ -+ bzip2 -9 $^ -+ -+%.pp: %.te -+ make -f ${SHAREDIR}/selinux/devel/Makefile $@ -+ -+clean: -+ rm -f *~ *.tc *.pp *.pp.bz2 -+ rm -rf tmp *.tar.gz -+ -+man: install -+ sepolicy manpage --domain ${TARGETS}_t -+ -+install: -+ semodule -i ${TARGETS} -+ -diff --git a/components/engine/contrib/selinux-euleros/docker-engine-selinux/README.md b/components/engine/contrib/selinux-euleros/docker-engine-selinux/README.md -new file mode 100644 -index 0000000000..7ea3117a89 ---- /dev/null -+++ b/components/engine/contrib/selinux-euleros/docker-engine-selinux/README.md -@@ -0,0 +1 @@ -+SELinux policy for docker -diff --git a/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.fc b/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.fc -new file mode 100644 -index 0000000000..e9bb863da0 ---- /dev/null -+++ b/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.fc -@@ -0,0 +1,20 @@ -+/root/\.docker gen_context(system_u:object_r:docker_home_t,s0) -+ -+/usr/bin/docker -- gen_context(system_u:object_r:docker_exec_t,s0) -+/usr/bin/dockerd -- gen_context(system_u:object_r:docker_exec_t,s0) -+/usr/lib/systemd/system/docker.service -- gen_context(system_u:object_r:docker_unit_file_t,s0) -+ -+/etc/docker(/.*)? gen_context(system_u:object_r:docker_config_t,s0) -+ -+/var/lib/docker(/.*)? gen_context(system_u:object_r:docker_var_lib_t,s0) -+/var/lib/kublet(/.*)? gen_context(system_u:object_r:docker_var_lib_t,s0) -+/var/lib/docker/vfs(/.*)? gen_context(system_u:object_r:svirt_sandbox_file_t,s0) -+ -+/var/run/docker\.pid -- gen_context(system_u:object_r:docker_var_run_t,s0) -+/var/run/docker\.sock -s gen_context(system_u:object_r:docker_var_run_t,s0) -+/var/run/docker-client(/.*)? gen_context(system_u:object_r:docker_var_run_t,s0) -+ -+/var/lib/docker/init(/.*)? gen_context(system_u:object_r:docker_share_t,s0) -+/var/lib/docker/containers/.*/hosts gen_context(system_u:object_r:docker_share_t,s0) -+/var/lib/docker/containers/.*/hostname gen_context(system_u:object_r:docker_share_t,s0) -+/var/lib/docker/.*/config\.env gen_context(system_u:object_r:docker_share_t,s0) -diff --git a/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.if b/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.if -new file mode 100644 -index 0000000000..ca075c05c5 ---- /dev/null -+++ b/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.if -@@ -0,0 +1,461 @@ -+ -+##

The open-source application container engine. -+ -+######################################## -+## -+## Execute docker in the docker domain. -+## -+## -+## -+## Domain allowed to transition. -+## -+## -+# -+interface(`docker_domtrans',` -+ gen_require(` -+ type docker_t, docker_exec_t; -+ ') -+ -+ corecmd_search_bin($1) -+ domtrans_pattern($1, docker_exec_t, docker_t) -+') -+ -+######################################## -+## -+## Execute docker in the caller domain. -+## -+## -+## -+## Domain allowed to transition. -+## -+## -+# -+interface(`docker_exec',` -+ gen_require(` -+ type docker_exec_t; -+ ') -+ -+ corecmd_search_bin($1) -+ can_exec($1, docker_exec_t) -+') -+ -+######################################## -+## -+## Search docker lib directories. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_search_lib',` -+ gen_require(` -+ type docker_var_lib_t; -+ ') -+ -+ allow $1 docker_var_lib_t:dir search_dir_perms; -+ files_search_var_lib($1) -+') -+ -+######################################## -+## -+## Execute docker lib directories. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_exec_lib',` -+ gen_require(` -+ type docker_var_lib_t; -+ ') -+ -+ allow $1 docker_var_lib_t:dir search_dir_perms; -+ can_exec($1, docker_var_lib_t) -+') -+ -+######################################## -+## -+## Read docker lib files. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_read_lib_files',` -+ gen_require(` -+ type docker_var_lib_t; -+ ') -+ -+ files_search_var_lib($1) -+ read_files_pattern($1, docker_var_lib_t, docker_var_lib_t) -+') -+ -+######################################## -+## -+## Read docker share files. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_read_share_files',` -+ gen_require(` -+ type docker_share_t; -+ ') -+ -+ files_search_var_lib($1) -+ read_files_pattern($1, docker_share_t, docker_share_t) -+') -+ -+######################################## -+## -+## Manage docker lib files. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_manage_lib_files',` -+ gen_require(` -+ type docker_var_lib_t; -+ ') -+ -+ files_search_var_lib($1) -+ manage_files_pattern($1, docker_var_lib_t, docker_var_lib_t) -+ manage_lnk_files_pattern($1, docker_var_lib_t, docker_var_lib_t) -+') -+ -+######################################## -+## -+## Manage docker lib directories. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_manage_lib_dirs',` -+ gen_require(` -+ type docker_var_lib_t; -+ ') -+ -+ files_search_var_lib($1) -+ manage_dirs_pattern($1, docker_var_lib_t, docker_var_lib_t) -+') -+ -+######################################## -+## -+## Create objects in a docker var lib directory -+## with an automatic type transition to -+## a specified private type. -+## -+## -+## -+## Domain allowed access. -+## -+## -+## -+## -+## The type of the object to create. -+## -+## -+## -+## -+## The class of the object to be created. -+## -+## -+## -+## -+## The name of the object being created. -+## -+## -+# -+interface(`docker_lib_filetrans',` -+ gen_require(` -+ type docker_var_lib_t; -+ ') -+ -+ filetrans_pattern($1, docker_var_lib_t, $2, $3, $4) -+') -+ -+######################################## -+## -+## Read docker PID files. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_read_pid_files',` -+ gen_require(` -+ type docker_var_run_t; -+ ') -+ -+ files_search_pids($1) -+ read_files_pattern($1, docker_var_run_t, docker_var_run_t) -+') -+ -+######################################## -+## -+## Execute docker server in the docker domain. -+## -+## -+## -+## Domain allowed to transition. -+## -+## -+# -+interface(`docker_systemctl',` -+ gen_require(` -+ type docker_t; -+ type docker_unit_file_t; -+ ') -+ -+ systemd_exec_systemctl($1) -+ init_reload_services($1) -+ systemd_read_fifo_file_passwd_run($1) -+ allow $1 docker_unit_file_t:file read_file_perms; -+ allow $1 docker_unit_file_t:service manage_service_perms; -+ -+ ps_process_pattern($1, docker_t) -+') -+ -+######################################## -+## -+## Read and write docker shared memory. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_rw_sem',` -+ gen_require(` -+ type docker_t; -+ ') -+ -+ allow $1 docker_t:sem rw_sem_perms; -+') -+ -+####################################### -+## -+## Read and write the docker pty type. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_use_ptys',` -+ gen_require(` -+ type docker_devpts_t; -+ ') -+ -+ allow $1 docker_devpts_t:chr_file rw_term_perms; -+') -+ -+####################################### -+## -+## Allow domain to create docker content -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_filetrans_named_content',` -+ -+ gen_require(` -+ type docker_var_lib_t; -+ type docker_share_t; -+ type docker_log_t; -+ type docker_var_run_t; -+ type docker_home_t; -+ ') -+ -+ files_pid_filetrans($1, docker_var_run_t, file, "docker.pid") -+ files_pid_filetrans($1, docker_var_run_t, sock_file, "docker.sock") -+ files_pid_filetrans($1, docker_var_run_t, dir, "docker-client") -+ files_var_lib_filetrans($1, docker_var_lib_t, dir, "docker") -+ filetrans_pattern($1, docker_var_lib_t, docker_share_t, file, "config.env") -+ filetrans_pattern($1, docker_var_lib_t, docker_share_t, file, "hosts") -+ filetrans_pattern($1, docker_var_lib_t, docker_share_t, file, "hostname") -+ filetrans_pattern($1, docker_var_lib_t, docker_share_t, file, "resolv.conf") -+ filetrans_pattern($1, docker_var_lib_t, docker_share_t, dir, "init") -+ userdom_admin_home_dir_filetrans($1, docker_home_t, dir, ".docker") -+') -+ -+######################################## -+## -+## Connect to docker over a unix stream socket. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_stream_connect',` -+ gen_require(` -+ type docker_t, docker_var_run_t; -+ ') -+ -+ files_search_pids($1) -+ stream_connect_pattern($1, docker_var_run_t, docker_var_run_t, docker_t) -+') -+ -+######################################## -+## -+## Connect to SPC containers over a unix stream socket. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_spc_stream_connect',` -+ gen_require(` -+ type spc_t, spc_var_run_t; -+ ') -+ -+ files_search_pids($1) -+ files_write_all_pid_sockets($1) -+ allow $1 spc_t:unix_stream_socket connectto; -+') -+ -+ -+######################################## -+## -+## All of the rules required to administrate -+## an docker environment -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`docker_admin',` -+ gen_require(` -+ type docker_t; -+ type docker_var_lib_t, docker_var_run_t; -+ type docker_unit_file_t; -+ type docker_lock_t; -+ type docker_log_t; -+ type docker_config_t; -+ ') -+ -+ allow $1 docker_t:process { ptrace signal_perms }; -+ ps_process_pattern($1, docker_t) -+ -+ admin_pattern($1, docker_config_t) -+ -+ files_search_var_lib($1) -+ admin_pattern($1, docker_var_lib_t) -+ -+ files_search_pids($1) -+ admin_pattern($1, docker_var_run_t) -+ -+ files_search_locks($1) -+ admin_pattern($1, docker_lock_t) -+ -+ logging_search_logs($1) -+ admin_pattern($1, docker_log_t) -+ -+ docker_systemctl($1) -+ admin_pattern($1, docker_unit_file_t) -+ allow $1 docker_unit_file_t:service all_service_perms; -+ -+ optional_policy(` -+ systemd_passwd_agent_exec($1) -+ systemd_read_fifo_file_passwd_run($1) -+ ') -+') -+ -+interface(`domain_stub_named_filetrans_domain',` -+ gen_require(` -+ attribute named_filetrans_domain; -+ ') -+') -+ -+interface(`lvm_stub',` -+ gen_require(` -+ type lvm_t; -+ ') -+') -+interface(`staff_stub',` -+ gen_require(` -+ type staff_t; -+ ') -+') -+interface(`virt_stub_svirt_sandbox_domain',` -+ gen_require(` -+ attribute svirt_sandbox_domain; -+ ') -+') -+interface(`virt_stub_svirt_sandbox_file',` -+ gen_require(` -+ type svirt_sandbox_file_t; -+ ') -+') -+interface(`fs_dontaudit_remount_tmpfs',` -+ gen_require(` -+ type tmpfs_t; -+ ') -+ -+ dontaudit $1 tmpfs_t:filesystem remount; -+') -+interface(`dev_dontaudit_list_all_dev_nodes',` -+ gen_require(` -+ type device_t; -+ ') -+ -+ dontaudit $1 device_t:dir list_dir_perms; -+') -+interface(`kernel_unlabeled_entry_type',` -+ gen_require(` -+ type unlabeled_t; -+ ') -+ -+ domain_entry_file($1, unlabeled_t) -+') -+interface(`kernel_unlabeled_domtrans',` -+ gen_require(` -+ type unlabeled_t; -+ ') -+ -+ read_lnk_files_pattern($1, unlabeled_t, unlabeled_t) -+ domain_transition_pattern($1, unlabeled_t, $2) -+ type_transition $1 unlabeled_t:process $2; -+') -+interface(`files_write_all_pid_sockets',` -+ gen_require(` -+ attribute pidfile; -+ ') -+ -+ allow $1 pidfile:sock_file write_sock_file_perms; -+') -+interface(`dev_dontaudit_mounton_sysfs',` -+ gen_require(` -+ type sysfs_t; -+ ') -+ -+ dontaudit $1 sysfs_t:dir mounton; -+') -diff --git a/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.te b/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.te -new file mode 100644 -index 0000000000..999742f302 ---- /dev/null -+++ b/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.te -@@ -0,0 +1,414 @@ -+policy_module(docker, 1.0.0) -+ -+######################################## -+# -+# Declarations -+# -+ -+## -+##

-+## Allow sandbox containers manage fuse files -+##

-+##
-+gen_tunable(virt_sandbox_use_fusefs, false) -+ -+## -+##

-+## Determine whether docker can -+## connect to all TCP ports. -+##

-+##
-+gen_tunable(docker_connect_any, false) -+ -+type docker_t; -+type docker_exec_t; -+init_daemon_domain(docker_t, docker_exec_t) -+domain_subj_id_change_exemption(docker_t) -+domain_role_change_exemption(docker_t) -+ -+type spc_t; -+domain_type(spc_t) -+role system_r types spc_t; -+ -+type spc_var_run_t; -+files_pid_file(spc_var_run_t) -+ -+type docker_var_lib_t; -+files_type(docker_var_lib_t) -+ -+type docker_home_t; -+userdom_user_home_content(docker_home_t) -+ -+type docker_config_t; -+files_config_file(docker_config_t) -+ -+type docker_lock_t; -+files_lock_file(docker_lock_t) -+ -+type docker_log_t; -+logging_log_file(docker_log_t) -+ -+type docker_tmp_t; -+files_tmp_file(docker_tmp_t) -+ -+type docker_tmpfs_t; -+files_tmpfs_file(docker_tmpfs_t) -+ -+type docker_var_run_t; -+files_pid_file(docker_var_run_t) -+ -+type docker_unit_file_t; -+systemd_unit_file(docker_unit_file_t) -+ -+type docker_devpts_t; -+term_pty(docker_devpts_t) -+ -+type docker_share_t; -+files_type(docker_share_t) -+ -+######################################## -+# -+# docker local policy -+# -+allow docker_t self:capability { chown kill fowner fsetid mknod net_admin net_bind_service net_raw setfcap }; -+allow docker_t self:tun_socket relabelto; -+allow docker_t self:process { getattr signal_perms setrlimit setfscreate }; -+allow docker_t self:fifo_file rw_fifo_file_perms; -+allow docker_t self:unix_stream_socket create_stream_socket_perms; -+allow docker_t self:tcp_socket create_stream_socket_perms; -+allow docker_t self:udp_socket create_socket_perms; -+allow docker_t self:capability2 block_suspend; -+ -+manage_files_pattern(docker_t, docker_home_t, docker_home_t) -+manage_dirs_pattern(docker_t, docker_home_t, docker_home_t) -+manage_lnk_files_pattern(docker_t, docker_home_t, docker_home_t) -+userdom_admin_home_dir_filetrans(docker_t, docker_home_t, dir, ".docker") -+ -+manage_dirs_pattern(docker_t, docker_config_t, docker_config_t) -+manage_files_pattern(docker_t, docker_config_t, docker_config_t) -+files_etc_filetrans(docker_t, docker_config_t, dir, "docker") -+ -+manage_dirs_pattern(docker_t, docker_lock_t, docker_lock_t) -+manage_files_pattern(docker_t, docker_lock_t, docker_lock_t) -+ -+manage_dirs_pattern(docker_t, docker_log_t, docker_log_t) -+manage_files_pattern(docker_t, docker_log_t, docker_log_t) -+manage_lnk_files_pattern(docker_t, docker_log_t, docker_log_t) -+logging_log_filetrans(docker_t, docker_log_t, { dir file lnk_file }) -+allow docker_t docker_log_t:dir_file_class_set { relabelfrom relabelto }; -+ -+manage_dirs_pattern(docker_t, docker_tmp_t, docker_tmp_t) -+manage_files_pattern(docker_t, docker_tmp_t, docker_tmp_t) -+manage_lnk_files_pattern(docker_t, docker_tmp_t, docker_tmp_t) -+files_tmp_filetrans(docker_t, docker_tmp_t, { dir file lnk_file }) -+ -+manage_dirs_pattern(docker_t, docker_tmpfs_t, docker_tmpfs_t) -+manage_files_pattern(docker_t, docker_tmpfs_t, docker_tmpfs_t) -+manage_lnk_files_pattern(docker_t, docker_tmpfs_t, docker_tmpfs_t) -+manage_fifo_files_pattern(docker_t, docker_tmpfs_t, docker_tmpfs_t) -+manage_chr_files_pattern(docker_t, docker_tmpfs_t, docker_tmpfs_t) -+manage_blk_files_pattern(docker_t, docker_tmpfs_t, docker_tmpfs_t) -+allow docker_t docker_tmpfs_t:dir relabelfrom; -+can_exec(docker_t, docker_tmpfs_t) -+fs_tmpfs_filetrans(docker_t, docker_tmpfs_t, { dir file }) -+allow docker_t docker_tmpfs_t:chr_file mounton; -+ -+manage_dirs_pattern(docker_t, docker_share_t, docker_share_t) -+manage_files_pattern(docker_t, docker_share_t, docker_share_t) -+manage_lnk_files_pattern(docker_t, docker_share_t, docker_share_t) -+allow docker_t docker_share_t:dir_file_class_set { relabelfrom relabelto }; -+ -+can_exec(docker_t, docker_share_t) -+#docker_filetrans_named_content(docker_t) -+ -+manage_dirs_pattern(docker_t, docker_var_lib_t, docker_var_lib_t) -+manage_chr_files_pattern(docker_t, docker_var_lib_t, docker_var_lib_t) -+manage_blk_files_pattern(docker_t, docker_var_lib_t, docker_var_lib_t) -+manage_files_pattern(docker_t, docker_var_lib_t, docker_var_lib_t) -+manage_lnk_files_pattern(docker_t, docker_var_lib_t, docker_var_lib_t) -+allow docker_t docker_var_lib_t:dir_file_class_set { relabelfrom relabelto }; -+files_var_lib_filetrans(docker_t, docker_var_lib_t, { dir file lnk_file }) -+ -+manage_dirs_pattern(docker_t, docker_var_run_t, docker_var_run_t) -+manage_files_pattern(docker_t, docker_var_run_t, docker_var_run_t) -+manage_sock_files_pattern(docker_t, docker_var_run_t, docker_var_run_t) -+manage_lnk_files_pattern(docker_t, docker_var_run_t, docker_var_run_t) -+files_pid_filetrans(docker_t, docker_var_run_t, { dir file lnk_file sock_file }) -+ -+allow docker_t docker_devpts_t:chr_file { relabelfrom rw_chr_file_perms setattr_chr_file_perms }; -+term_create_pty(docker_t, docker_devpts_t) -+ -+kernel_read_system_state(docker_t) -+kernel_read_network_state(docker_t) -+kernel_read_all_sysctls(docker_t) -+kernel_rw_net_sysctls(docker_t) -+kernel_setsched(docker_t) -+kernel_read_all_proc(docker_t) -+ -+domain_use_interactive_fds(docker_t) -+domain_dontaudit_read_all_domains_state(docker_t) -+ -+corecmd_exec_bin(docker_t) -+corecmd_exec_shell(docker_t) -+ -+corenet_tcp_bind_generic_node(docker_t) -+corenet_tcp_sendrecv_generic_if(docker_t) -+corenet_tcp_sendrecv_generic_node(docker_t) -+corenet_tcp_sendrecv_generic_port(docker_t) -+corenet_tcp_bind_all_ports(docker_t) -+corenet_tcp_connect_http_port(docker_t) -+corenet_tcp_connect_commplex_main_port(docker_t) -+corenet_udp_sendrecv_generic_if(docker_t) -+corenet_udp_sendrecv_generic_node(docker_t) -+corenet_udp_sendrecv_all_ports(docker_t) -+corenet_udp_bind_generic_node(docker_t) -+corenet_udp_bind_all_ports(docker_t) -+ -+files_read_config_files(docker_t) -+files_dontaudit_getattr_all_dirs(docker_t) -+files_dontaudit_getattr_all_files(docker_t) -+ -+fs_read_cgroup_files(docker_t) -+fs_read_tmpfs_symlinks(docker_t) -+fs_search_all(docker_t) -+fs_getattr_all_fs(docker_t) -+ -+storage_raw_rw_fixed_disk(docker_t) -+ -+auth_use_nsswitch(docker_t) -+auth_dontaudit_getattr_shadow(docker_t) -+ -+init_read_state(docker_t) -+init_status(docker_t) -+ -+logging_send_audit_msgs(docker_t) -+logging_send_syslog_msg(docker_t) -+ -+miscfiles_read_localization(docker_t) -+ -+mount_domtrans(docker_t) -+ -+seutil_read_default_contexts(docker_t) -+seutil_read_config(docker_t) -+ -+sysnet_dns_name_resolve(docker_t) -+sysnet_exec_ifconfig(docker_t) -+ -+optional_policy(` -+ rpm_exec(docker_t) -+ rpm_read_db(docker_t) -+ rpm_exec(docker_t) -+') -+ -+optional_policy(` -+ fstools_domtrans(docker_t) -+') -+ -+optional_policy(` -+ iptables_domtrans(docker_t) -+') -+ -+optional_policy(` -+ openvswitch_stream_connect(docker_t) -+') -+ -+allow docker_t self:capability { dac_override setgid setpcap setuid sys_admin sys_boot sys_chroot sys_ptrace }; -+ -+allow docker_t self:process { getcap setcap setexec setpgid setsched signal_perms }; -+ -+allow docker_t self:netlink_route_socket rw_netlink_socket_perms;; -+allow docker_t self:netlink_audit_socket create_netlink_socket_perms; -+allow docker_t self:unix_dgram_socket { create_socket_perms sendto }; -+allow docker_t self:unix_stream_socket { create_stream_socket_perms connectto }; -+ -+allow docker_t docker_var_lib_t:dir mounton; -+allow docker_t docker_var_lib_t:chr_file mounton; -+can_exec(docker_t, docker_var_lib_t) -+ -+kernel_dontaudit_setsched(docker_t) -+kernel_get_sysvipc_info(docker_t) -+kernel_request_load_module(docker_t) -+kernel_mounton_messages(docker_t) -+kernel_mounton_all_proc(docker_t) -+kernel_mounton_all_sysctls(docker_t) -+kernel_unlabeled_entry_type(spc_t) -+kernel_unlabeled_domtrans(docker_t, spc_t) -+ -+dev_getattr_all(docker_t) -+dev_getattr_sysfs_fs(docker_t) -+dev_read_urand(docker_t) -+dev_read_lvm_control(docker_t) -+dev_rw_sysfs(docker_t) -+dev_rw_loop_control(docker_t) -+dev_rw_lvm_control(docker_t) -+ -+files_getattr_isid_type_dirs(docker_t) -+files_manage_isid_type_dirs(docker_t) -+files_manage_isid_type_files(docker_t) -+files_manage_isid_type_symlinks(docker_t) -+files_manage_isid_type_chr_files(docker_t) -+files_manage_isid_type_blk_files(docker_t) -+files_exec_isid_files(docker_t) -+files_mounton_isid(docker_t) -+files_mounton_non_security(docker_t) -+files_mounton_isid_type_chr_file(docker_t) -+ -+fs_mount_all_fs(docker_t) -+fs_unmount_all_fs(docker_t) -+fs_remount_all_fs(docker_t) -+files_mounton_isid(docker_t) -+fs_manage_cgroup_dirs(docker_t) -+fs_manage_cgroup_files(docker_t) -+fs_relabelfrom_xattr_fs(docker_t) -+fs_relabelfrom_tmpfs(docker_t) -+fs_read_tmpfs_symlinks(docker_t) -+fs_list_hugetlbfs(docker_t) -+ -+term_use_generic_ptys(docker_t) -+term_use_ptmx(docker_t) -+term_getattr_pty_fs(docker_t) -+term_relabel_pty_fs(docker_t) -+term_mounton_unallocated_ttys(docker_t) -+ -+modutils_domtrans_insmod(docker_t) -+ -+systemd_status_all_unit_files(docker_t) -+systemd_start_systemd_services(docker_t) -+ -+userdom_stream_connect(docker_t) -+userdom_search_user_home_content(docker_t) -+userdom_read_all_users_state(docker_t) -+userdom_relabel_user_home_files(docker_t) -+userdom_relabel_user_tmp_files(docker_t) -+userdom_relabel_user_tmp_dirs(docker_t) -+ -+optional_policy(` -+ gpm_getattr_gpmctl(docker_t) -+') -+ -+optional_policy(` -+ dbus_system_bus_client(docker_t) -+ init_dbus_chat(docker_t) -+ init_start_transient_unit(docker_t) -+ -+ optional_policy(` -+ systemd_dbus_chat_logind(docker_t) -+ ') -+ -+ optional_policy(` -+ firewalld_dbus_chat(docker_t) -+ ') -+') -+ -+optional_policy(` -+ udev_read_db(docker_t) -+') -+ -+optional_policy(` -+ virt_read_config(docker_t) -+ virt_exec(docker_t) -+ virt_stream_connect(docker_t) -+ virt_stream_connect_sandbox(docker_t) -+ virt_exec_sandbox_files(docker_t) -+ virt_manage_sandbox_files(docker_t) -+ virt_relabel_sandbox_filesystem(docker_t) -+ virt_transition_svirt_sandbox(docker_t, system_r) -+ virt_mounton_sandbox_file(docker_t) -+# virt_attach_sandbox_tun_iface(docker_t) -+ allow docker_t svirt_sandbox_domain:tun_socket relabelfrom; -+') -+ -+tunable_policy(`docker_connect_any',` -+ corenet_tcp_connect_all_ports(docker_t) -+ corenet_sendrecv_all_packets(docker_t) -+ corenet_tcp_sendrecv_all_ports(docker_t) -+') -+ -+######################################## -+# -+# spc local policy -+# -+domain_entry_file(spc_t, docker_share_t) -+domain_entry_file(spc_t, docker_var_lib_t) -+role system_r types spc_t; -+ -+domain_entry_file(spc_t, docker_share_t) -+domain_entry_file(spc_t, docker_var_lib_t) -+domtrans_pattern(docker_t, docker_share_t, spc_t) -+domtrans_pattern(docker_t, docker_var_lib_t, spc_t) -+allow docker_t spc_t:process { setsched signal_perms }; -+ps_process_pattern(docker_t, spc_t) -+allow docker_t spc_t:socket_class_set { relabelto relabelfrom }; -+ -+optional_policy(` -+ dbus_chat_system_bus(spc_t) -+') -+ -+optional_policy(` -+ unconfined_domain_noaudit(spc_t) -+') -+ -+optional_policy(` -+ unconfined_domain(docker_t) -+') -+ -+optional_policy(` -+ virt_transition_svirt_sandbox(spc_t, system_r) -+') -+ -+######################################## -+# -+# docker upstream policy -+# -+ -+optional_policy(` -+# domain_stub_named_filetrans_domain() -+ gen_require(` -+ attribute named_filetrans_domain; -+ ') -+ -+ docker_filetrans_named_content(named_filetrans_domain) -+') -+ -+optional_policy(` -+ lvm_stub() -+ docker_rw_sem(lvm_t) -+') -+ -+optional_policy(` -+ staff_stub() -+ docker_stream_connect(staff_t) -+ docker_exec(staff_t) -+') -+ -+optional_policy(` -+ virt_stub_svirt_sandbox_domain() -+ virt_stub_svirt_sandbox_file() -+ allow svirt_sandbox_domain self:netlink_kobject_uevent_socket create_socket_perms; -+ docker_read_share_files(svirt_sandbox_domain) -+ docker_lib_filetrans(svirt_sandbox_domain,svirt_sandbox_file_t, sock_file) -+ docker_use_ptys(svirt_sandbox_domain) -+ docker_spc_stream_connect(svirt_sandbox_domain) -+ fs_list_tmpfs(svirt_sandbox_domain) -+ fs_rw_hugetlbfs_files(svirt_sandbox_domain) -+ fs_dontaudit_remount_tmpfs(svirt_sandbox_domain) -+ dev_dontaudit_mounton_sysfs(svirt_sandbox_domain) -+ -+ tunable_policy(`virt_sandbox_use_fusefs',` -+ fs_manage_fusefs_dirs(svirt_sandbox_domain) -+ fs_manage_fusefs_files(svirt_sandbox_domain) -+ fs_manage_fusefs_symlinks(svirt_sandbox_domain) -+ ') -+ gen_require(` -+ attribute domain; -+ ') -+ -+ dontaudit svirt_sandbox_domain domain:key {search link}; -+') -+ -+optional_policy(` -+ gen_require(` -+ type pcp_pmcd_t; -+ ') -+ docker_manage_lib_files(pcp_pmcd_t) -+') -diff --git a/components/engine/hack/make/.build-rpm/docker-engine-selinux-euleros.spec b/components/engine/hack/make/.build-rpm/docker-engine-selinux-euleros.spec -new file mode 100644 -index 0000000000..a5c497d93a ---- /dev/null -+++ b/components/engine/hack/make/.build-rpm/docker-engine-selinux-euleros.spec -@@ -0,0 +1,109 @@ -+# Some bits borrowed from the openstack-selinux package -+%global _version 18.09.0.3 -+%global _release 0.0.20190123.161547.git021da66 -+Name: docker-engine-selinux -+Version: %{_version} -+Release: %{_release}%{?dist} -+Summary: SELinux Policies for the open-source application container engine -+BuildArch: noarch -+Group: Tools/Docker -+ -+License: GPLv2 -+Source: %{name}.tar.gz -+ -+URL: https://dockerproject.org -+ -+# Version of SELinux we were using -+%if 0%{?fedora} == 20 -+%global selinux_policyver 3.12.1-197 -+%endif # fedora 20 -+%if 0%{?fedora} == 21 -+%global selinux_policyver 3.13.1-105 -+%endif # fedora 21 -+%if 0%{?fedora} >= 22 -+%global selinux_policyver 3.13.1-128 -+%endif # fedora 22 -+%if 0%{?centos} >= 7 || 0%{?rhel} >= 7 || 0%{?oraclelinux} >= 7 -+%global selinux_policyver 3.13.1-23 -+%endif # centos,rhel,oraclelinux 7 -+ -+%global selinuxtype targeted -+%global moduletype services -+%global modulenames docker -+ -+Requires(post): selinux-policy-base >= %{selinux_policyver}, selinux-policy-targeted >= %{selinux_policyver}, policycoreutils, policycoreutils-python libselinux-utils -+BuildRequires: selinux-policy selinux-policy-devel -+ -+# conflicting packages -+Conflicts: docker-selinux -+ -+# Usage: _format var format -+# Expand 'modulenames' into various formats as needed -+# Format must contain '$x' somewhere to do anything useful -+%global _format() export %1=""; for x in %{modulenames}; do %1+=%2; %1+=" "; done; -+ -+# Relabel files -+%global relabel_files() \ -+ /sbin/restorecon -R %{_bindir}/docker %{_localstatedir}/run/docker.sock %{_localstatedir}/run/docker.pid %{_sysconfdir}/docker %{_localstatedir}/log/docker %{_localstatedir}/log/lxc %{_localstatedir}/lock/lxc %{_usr}/lib/systemd/system/docker.service /root/.docker &> /dev/null || : \ -+ -+%description -+SELinux policy modules for use with Docker -+ -+%prep -+%if 0%{?centos} <= 6 -+%setup -n %{name} -+%else -+%autosetup -n %{name} -+%endif -+ -+%build -+make SHARE="%{_datadir}" TARGETS="%{modulenames}" -+ -+%install -+ -+# Install SELinux interfaces -+%_format INTERFACES $x.if -+install -d %{buildroot}%{_datadir}/selinux/devel/include/%{moduletype} -+install -p -m 644 $INTERFACES %{buildroot}%{_datadir}/selinux/devel/include/%{moduletype} -+ -+# Install policy modules -+%_format MODULES $x.pp.bz2 -+install -d %{buildroot}%{_datadir}/selinux/packages -+install -m 0644 $MODULES %{buildroot}%{_datadir}/selinux/packages -+ -+%post -+# -+# Install all modules in a single transaction -+# -+if [ $1 -eq 1 ]; then -+ %{_sbindir}/setsebool -P -N virt_use_nfs=1 virt_sandbox_use_all_caps=1 -+fi -+%_format MODULES %{_datadir}/selinux/packages/$x.pp.bz2 -+%{_sbindir}/semodule -n -s %{selinuxtype} -i $MODULES -+if %{_sbindir}/selinuxenabled ; then -+ %{_sbindir}/load_policy -+ %relabel_files -+ if [ $1 -eq 1 ]; then -+ restorecon -R %{_sharedstatedir}/docker -+ fi -+fi -+ -+%postun -+if [ $1 -eq 0 ]; then -+ %{_sbindir}/semodule -n -r %{modulenames} &> /dev/null || : -+ if %{_sbindir}/selinuxenabled ; then -+ %{_sbindir}/load_policy -+ %relabel_files -+ fi -+fi -+ -+%files -+%doc LICENSE -+%defattr(-,root,root,0755) -+%attr(0644,root,root) %{_datadir}/selinux/packages/*.pp.bz2 -+%attr(0644,root,root) %{_datadir}/selinux/devel/include/%{moduletype}/*.if -+ -+%changelog -+* Tue Dec 1 2015 Jessica Frazelle 1.9.1-1 -+- add licence to rpm -+- add selinux-policy and docker-engine-selinux rpm --- -2.17.1 - diff --git a/patch/0081-runtime-spec-revert-the-modify-of-runtime-spe.patch b/patch/0081-runtime-spec-revert-the-modify-of-runtime-spe.patch deleted file mode 100644 index 15822e0..0000000 --- a/patch/0081-runtime-spec-revert-the-modify-of-runtime-spe.patch +++ /dev/null @@ -1,51 +0,0 @@ -From c1b7332e8f531e53062c740a16f953cd37661d30 Mon Sep 17 00:00:00 2001 -From: leizhongkai -Date: Thu, 24 Jan 2019 20:24:08 +0800 -Subject: [PATCH 081/111] runtime-spec: revert the modify of runtime - spec - -reason:revert the modify of runtime spec,make the compatibility in runc - -Change-Id: Ia294a169ff15c860c7db3b7a9ab14cecb605cfef -Signed-off-by: leizhongkai ---- - .../runtime-spec/specs-go/config.go | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - -diff --git a/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go -index aab7b8a098..46049b3bfa 100644 ---- a/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go -+++ b/components/engine/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go -@@ -256,20 +256,20 @@ type LinuxThrottleDevice struct { - - // LinuxBlockIO for Linux cgroup 'blkio' resource management - type LinuxBlockIO struct { -- // Specifies per cgroup weight, range is from 10 to 1000 -- Weight *uint16 `json:"blkioWeight,omitempty"` -- // Specifies tasks' weight in the given cgroup while competing with the cgroup's child cgroups, range is from 10 to 1000, CFQ scheduler only -- LeafWeight *uint16 `json:"blkioLeafWeight,omitempty"` -+ // Specifies per cgroup weight -+ Weight *uint16 `json:"weight,omitempty"` -+ // Specifies tasks' weight in the given cgroup while competing with the cgroup's child cgroups, CFQ scheduler only -+ LeafWeight *uint16 `json:"leafWeight,omitempty"` - // Weight per cgroup per device, can override BlkioWeight -- WeightDevice []LinuxWeightDevice `json:"blkioWeightDevice,omitempty"` -+ WeightDevice []LinuxWeightDevice `json:"weightDevice,omitempty"` - // IO read rate limit per cgroup per device, bytes per second -- ThrottleReadBpsDevice []LinuxThrottleDevice `json:"blkioThrottleReadBpsDevice,omitempty"` -+ ThrottleReadBpsDevice []LinuxThrottleDevice `json:"throttleReadBpsDevice,omitempty"` - // IO write rate limit per cgroup per device, bytes per second -- ThrottleWriteBpsDevice []LinuxThrottleDevice `json:"blkioThrottleWriteBpsDevice,omitempty"` -+ ThrottleWriteBpsDevice []LinuxThrottleDevice `json:"throttleWriteBpsDevice,omitempty"` - // IO read rate limit per cgroup per device, IO per second -- ThrottleReadIOPSDevice []LinuxThrottleDevice `json:"blkioThrottleReadIOPSDevice,omitempty"` -+ ThrottleReadIOPSDevice []LinuxThrottleDevice `json:"throttleReadIOPSDevice,omitempty"` - // IO write rate limit per cgroup per device, IO per second -- ThrottleWriteIOPSDevice []LinuxThrottleDevice `json:"blkioThrottleWriteIOPSDevice,omitempty"` -+ ThrottleWriteIOPSDevice []LinuxThrottleDevice `json:"throttleWriteIOPSDevice,omitempty"` - } - - // LinuxMemory for Linux cgroup 'memory' resource management --- -2.17.1 - diff --git a/patch/0083-test-fix-start-paused-container.patch b/patch/0083-test-fix-start-paused-container.patch deleted file mode 100644 index 2255756..0000000 --- a/patch/0083-test-fix-start-paused-container.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 3e2f675c4e55a73e9ac2ae7b6c0dfca8d37dd9d8 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 24 Jan 2019 16:20:24 +0800 -Subject: [PATCH 083/111] test: fix start paused container - -reason: please unpause before start. - -Change-Id: I435ab7e5cfe4aaed8c6c4e502ca64b0c65fff6a5 -Signed-off-by: jingrui ---- - components/engine/integration-cli/docker_cli_daemon_test.go | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/components/engine/integration-cli/docker_cli_daemon_test.go b/components/engine/integration-cli/docker_cli_daemon_test.go -index d3cd5f1676..02c42c22e2 100644 ---- a/components/engine/integration-cli/docker_cli_daemon_test.go -+++ b/components/engine/integration-cli/docker_cli_daemon_test.go -@@ -1627,9 +1627,8 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithPausedContainer(c *check.C) { - case <-time.After(5 * time.Second): - c.Fatal("Waiting on start a container timed out") - case err := <-errchan: -- if err != nil { -- c.Fatal(err) -- } -+ c.Assert(err, check.NotNil, check.Commentf("cannot start a paused container")) -+ s.d.Cmd("unpause", "test") - } - } - --- -2.17.1 - diff --git a/patch/0084-test-skip-pause-test-with-ctr.patch b/patch/0084-test-skip-pause-test-with-ctr.patch deleted file mode 100644 index 30e3af1..0000000 --- a/patch/0084-test-skip-pause-test-with-ctr.patch +++ /dev/null @@ -1,47 +0,0 @@ -From c6edc1d912211c8b35df6c28033fb577a899573e Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 24 Jan 2019 16:28:45 +0800 -Subject: [PATCH 084/111] test: skip pause test with ctr - -reason: pause managed by docker only - -Change-Id: I8aae73e4ab1e0bf9ed639495aa112469ac3630d9 -Signed-off-by: jingrui ---- - components/engine/integration-cli/docker_cli_daemon_test.go | 3 ++- - components/engine/integration-cli/requirements_test.go | 5 +++++ - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/components/engine/integration-cli/docker_cli_daemon_test.go b/components/engine/integration-cli/docker_cli_daemon_test.go -index 02c42c22e2..467edb04b4 100644 ---- a/components/engine/integration-cli/docker_cli_daemon_test.go -+++ b/components/engine/integration-cli/docker_cli_daemon_test.go -@@ -2049,7 +2049,8 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonCrash(c *check.C) { - - // TestDaemonRestartWithUnpausedRunningContainer requires live restore of running containers. - func (s *DockerDaemonSuite) TestDaemonRestartWithUnpausedRunningContainer(t *check.C) { -- testRequires(t, DaemonIsLinux) -+ testRequires(t, DaemonIsLinux, SupportCtr) -+ - s.d.StartWithBusybox(t, "--live-restore") - - cid, err := s.d.Cmd("run", "-d", "--name", "test", "busybox", "top") -diff --git a/components/engine/integration-cli/requirements_test.go b/components/engine/integration-cli/requirements_test.go -index 28be59cd2c..4647ce8ccc 100644 ---- a/components/engine/integration-cli/requirements_test.go -+++ b/components/engine/integration-cli/requirements_test.go -@@ -38,6 +38,11 @@ func DaemonIsWindowsAtLeastBuild(buildNumber int) func() bool { - } - } - -+func SupportCtr() bool { -+ // not support ctr now. -+ return false -+} -+ - func DaemonIsLinux() bool { - return testEnv.OSType == "linux" - } --- -2.17.1 - diff --git a/patch/0085-event-log-detailed-event-with-info-level.patch b/patch/0085-event-log-detailed-event-with-info-level.patch deleted file mode 100644 index bb79570..0000000 --- a/patch/0085-event-log-detailed-event-with-info-level.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 2a3375c72a5d535864561a0a5fd46dc1fee17013 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Fri, 25 Jan 2019 16:56:08 +0800 -Subject: [PATCH 085/111] event: log detailed event with info level - -reason: DFX improve event level and record with detailed info. - -Change-Id: Ibb5b1058b84de39f9f7058a46a15c2dbd27bc746 -Signed-off-by: jingrui ---- - .../engine/libcontainerd/client_daemon.go | 51 ++++++++++++++++++- - 1 file changed, 49 insertions(+), 2 deletions(-) - -diff --git a/components/engine/libcontainerd/client_daemon.go b/components/engine/libcontainerd/client_daemon.go -index cb9cb43a73..491bda281c 100644 ---- a/components/engine/libcontainerd/client_daemon.go -+++ b/components/engine/libcontainerd/client_daemon.go -@@ -791,8 +791,6 @@ func (c *client) processEventStream(ctx context.Context, ns string) { - continue - } - -- c.logger.WithField("topic", ev.Topic).Debug("event") -- - switch t := v.(type) { - case *apievents.TaskCreate: - et = EventCreate -@@ -801,6 +799,11 @@ func (c *client) processEventStream(ctx context.Context, ns string) { - ProcessID: t.ContainerID, - Pid: t.Pid, - } -+ c.logger.WithFields(logrus.Fields{ -+ "topic": ev.Topic, -+ "containerID": t.ContainerID, -+ "Pid": t.Pid, -+ }).Infof("event") - case *apievents.TaskStart: - et = EventStart - ei = EventInfo{ -@@ -808,6 +811,11 @@ func (c *client) processEventStream(ctx context.Context, ns string) { - ProcessID: t.ContainerID, - Pid: t.Pid, - } -+ c.logger.WithFields(logrus.Fields{ -+ "topic": ev.Topic, -+ "containerID": t.ContainerID, -+ "Pid": t.Pid, -+ }).Infof("event") - case *apievents.TaskExit: - et = EventExit - ei = EventInfo{ -@@ -817,6 +825,13 @@ func (c *client) processEventStream(ctx context.Context, ns string) { - ExitCode: t.ExitStatus, - ExitedAt: t.ExitedAt, - } -+ c.logger.WithFields(logrus.Fields{ -+ "topic": ev.Topic, -+ "containerID": t.ContainerID, -+ "Pid": t.Pid, -+ "ExitStatus": t.ExitStatus, -+ "ExitedAt": t.ExitedAt, -+ }).Infof("event") - case *apievents.TaskOOM: - et = EventOOM - ei = EventInfo{ -@@ -824,12 +839,22 @@ func (c *client) processEventStream(ctx context.Context, ns string) { - OOMKilled: true, - } - oomKilled = true -+ c.logger.WithFields(logrus.Fields{ -+ "topic": ev.Topic, -+ "containerID": t.ContainerID, -+ "OOMKilled": true, -+ }).Infof("event") - case *apievents.TaskExecAdded: - et = EventExecAdded - ei = EventInfo{ - ContainerID: t.ContainerID, - ProcessID: t.ExecID, - } -+ c.logger.WithFields(logrus.Fields{ -+ "topic": ev.Topic, -+ "containerID": t.ContainerID, -+ "execID": t.ExecID, -+ }).Infof("event") - case *apievents.TaskExecStarted: - et = EventExecStarted - ei = EventInfo{ -@@ -837,16 +862,38 @@ func (c *client) processEventStream(ctx context.Context, ns string) { - ProcessID: t.ExecID, - Pid: t.Pid, - } -+ c.logger.WithFields(logrus.Fields{ -+ "topic": ev.Topic, -+ "containerID": t.ContainerID, -+ "execID": t.ExecID, -+ "Pid": t.Pid, -+ }).Infof("event") - case *apievents.TaskPaused: - et = EventPaused - ei = EventInfo{ - ContainerID: t.ContainerID, - } -+ c.logger.WithFields(logrus.Fields{ -+ "topic": ev.Topic, -+ "containerID": t.ContainerID, -+ }).Infof("event") - case *apievents.TaskResumed: - et = EventResumed - ei = EventInfo{ - ContainerID: t.ContainerID, - } -+ c.logger.WithFields(logrus.Fields{ -+ "topic": ev.Topic, -+ "containerID": t.ContainerID, -+ }).Infof("event") -+ case *apievents.TaskDelete: -+ c.logger.WithFields(logrus.Fields{ -+ "topic": ev.Topic, -+ "containerID": t.ContainerID, -+ "Pid": t.Pid, -+ "ExitStatus": t.ExitStatus, -+ "ExitedAt": t.ExitedAt, -+ }).Infof("event") - default: - c.logger.WithFields(logrus.Fields{ - "topic": ev.Topic, --- -2.17.1 - diff --git a/patch/0086-restart-fix-daemon-restart-with-restart-alway.patch b/patch/0086-restart-fix-daemon-restart-with-restart-alway.patch deleted file mode 100644 index 688f9b8..0000000 --- a/patch/0086-restart-fix-daemon-restart-with-restart-alway.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 99b7f823b7dfe88dc2d4f4073f10cbf3a437bd81 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Fri, 25 Jan 2019 16:59:26 +0800 -Subject: [PATCH 086/111] restart: fix daemon restart with - restart=always container - -reason: fix daemon gracefully restart while container is start with -restart=always. restart-manager blocked to start container while -restoring, when restoring start container successful, the -restart-manager will start container but error with "id already in use". - -related testcase: -TestDaemonRestartKillContainers -TestDockerNetworkHostModeUngracefulDaemonRestart - -ref: -- https://github.com/moby/moby/issues/38249 - -Change-Id: I2545286a8371cb656ec6574d23cd15de4ba60283 -Signed-off-by: jingrui ---- - components/engine/daemon/daemon_unix.go | 3 +++ - components/engine/daemon/start.go | 9 +++++++++ - 2 files changed, 12 insertions(+) - -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index b20c66e27b..9abc9a329a 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -1291,6 +1291,9 @@ func setupDaemonRootPropagation(cfg *config.Config) error { - return nil - } - -+ if err := os.MkdirAll(filepath.Dir(cleanupFile), 0700); err != nil { -+ return errors.Wrap(err, "error mkdir parent to signal mount cleanup on shutdown") -+ } - if err := ioutil.WriteFile(cleanupFile, nil, 0600); err != nil { - return errors.Wrap(err, "error writing file to signal mount cleanup on shutdown") - } -diff --git a/components/engine/daemon/start.go b/components/engine/daemon/start.go -index c00bd9ceb2..96ae45e11e 100644 ---- a/components/engine/daemon/start.go -+++ b/components/engine/daemon/start.go -@@ -108,6 +108,15 @@ func (daemon *Daemon) containerStart(container *container.Container, checkpoint - return nil - } - -+ // fix restartManager restarted the container is already started by restore. -+ if container.Running { -+ _, err := daemon.containerd.Status(context.Background(), container.ID) -+ if err == nil { -+ logrus.Warnf("skip starting the container is exist and running.") -+ return nil -+ } -+ } -+ - if container.RemovalInProgress || container.Dead { - return errdefs.Conflict(errors.New("container is marked for removal and cannot be started")) - } --- -2.17.1 - diff --git a/patch/0088-attach-add-timeout-return-for-getExitStatus.patch b/patch/0088-attach-add-timeout-return-for-getExitStatus.patch deleted file mode 100644 index 5182124..0000000 --- a/patch/0088-attach-add-timeout-return-for-getExitStatus.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 4f99f2ea6fac5d585cee3b7362b109dcf869beda Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Wed, 30 Jan 2019 13:42:34 +0800 -Subject: [PATCH 088/111] attach: add timeout return for getExitStatus - -reason:In cli/command/container/attach.go, func getExitStatus() will -return until container turn to unrunning state. When we excute docker -attach and other commands inside container together, for the state of -container will not change, docker attach command is stuck. - -Change-Id: Ifda6096643c659341fd6d343eb4a8cbf08e5a71c -Signed-off-by: zhangyu235 ---- - components/cli/cli/command/container/attach.go | 4 ++++ - 5 files changed, 10 insertions(+), 6 deletions(-) - -diff --git a/components/cli/cli/command/container/attach.go b/components/cli/cli/command/container/attach.go -index de96a3b7d8..ff1014d70c 100644 ---- a/components/cli/cli/command/container/attach.go -+++ b/components/cli/cli/command/container/attach.go -@@ -5,6 +5,7 @@ import ( - "fmt" - "io" - "net/http/httputil" -+ "time" - - "github.com/docker/cli/cli" - "github.com/docker/cli/cli/command" -@@ -150,6 +151,7 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error { - } - - func getExitStatus(errC <-chan error, resultC <-chan container.ContainerWaitOKBody) error { -+ timeout := time.NewTimer(time.Second) - select { - case result := <-resultC: - if result.Error != nil { -@@ -160,6 +162,8 @@ func getExitStatus(errC <-chan error, resultC <-chan container.ContainerWaitOKBo - } - case err := <-errC: - return err -+ case <-timeout.C: -+ return fmt.Errorf("Wait container status timeout.") - } - - return nil --- -2.17.1 - diff --git a/patch/0089-libcontainerd-fix-stuck-when-containerd-in-T-.patch b/patch/0089-libcontainerd-fix-stuck-when-containerd-in-T-.patch deleted file mode 100644 index 7f55732..0000000 --- a/patch/0089-libcontainerd-fix-stuck-when-containerd-in-T-.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 9a48f9b439a03e7fd5eeec4ff2cebac4cddf669f Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 30 Jan 2019 21:28:16 +0800 -Subject: [PATCH 089/111] libcontainerd: fix stuck when containerd in - T-state - -reason: when containerd is alive but not responding, shall restart -containerd avoid cmd stuck. - -Change-Id: Iab220c8988b50b39f4fd84be9454a0b097968751 -Signed-off-by: jingrui ---- - components/engine/libcontainerd/supervisor/remote_daemon.go | 2 +- - 5 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/components/engine/libcontainerd/supervisor/remote_daemon.go b/components/engine/libcontainerd/supervisor/remote_daemon.go -index 095300f753..c5da3a56fe 100644 ---- a/components/engine/libcontainerd/supervisor/remote_daemon.go -+++ b/components/engine/libcontainerd/supervisor/remote_daemon.go -@@ -307,7 +307,7 @@ func (r *remote) monitorDaemon(ctx context.Context) { - r.logger.WithError(err).WithField("binary", binaryName).Debug("daemon is not responding") - - transientFailureCount++ -- if transientFailureCount < maxConnectionRetryCount || system.IsProcessAlive(r.daemonPid) { -+ if transientFailureCount < maxConnectionRetryCount { - delay = time.After(time.Duration(transientFailureCount) * 200 * time.Millisecond) - continue - } --- -2.17.1 - diff --git a/patch/0090-overlay2-Use-index-off-if-possible.patch b/patch/0090-overlay2-Use-index-off-if-possible.patch deleted file mode 100644 index 6f48d99..0000000 --- a/patch/0090-overlay2-Use-index-off-if-possible.patch +++ /dev/null @@ -1,73 +0,0 @@ -From b2750c914429b4f981848d0c829ddfc0c8acc37e Mon Sep 17 00:00:00 2001 -From: xiadanni -Date: Fri, 1 Feb 2019 01:03:12 +0800 -Subject: [PATCH 090/111] overlay2: Use index=off if possible - -reason: Docker overlay driver can't work with index=on feature of -the Linux kernel "overlay" filesystem. In case the global -default is set to "yes", Docker will fail with EBUSY when -trying to mount. - -Cherry-pick from https://github.com/moby/moby/pull/37993/commits/8422d85087bfa770b62ef4e1daaca95ee6783d86 - -Change-Id: Iad1addaca9983ba35c466951e04c7034b0a18fab -Signed-off-by: Kir Kolyshkin -Signed-off-by: xiadanni ---- - .../daemon/graphdriver/overlay2/overlay.go | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index cf8993e9f3..d87f979673 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -111,6 +111,8 @@ var ( - - useNaiveDiffLock sync.Once - useNaiveDiffOnly bool -+ -+ indexOff string - ) - - func init() { -@@ -228,7 +230,18 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap - return nil, fmt.Errorf("Storage Option overlay2.size only supported for backingFS XFS or ext4. Found %v", backingFs) - } - -- logger.Debugf("backingFs=%s, projectQuotaSupported=%v", backingFs, projectQuotaSupported) -+ // figure out whether "index=off" option is recognized by the kernel -+ _, err = os.Stat("/sys/module/overlay/parameters/index") -+ switch { -+ case err == nil: -+ indexOff = "index=off," -+ case os.IsNotExist(err): -+ // old kernel, no index -- do nothing -+ default: -+ logger.Warnf("Unable to detect whether overlay kernel module supports index parameter: %s", err) -+ } -+ -+ logger.Debugf("backingFs=%s, projectQuotaSupported=%v, indexOff=%q", backingFs, projectQuotaSupported, indexOff) - - return d, nil - } -@@ -632,7 +645,7 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e - for i, s := range splitLowers { - absLowers[i] = path.Join(d.home, s) - } -- opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", strings.Join(absLowers, ":"), path.Join(dir, "diff"), path.Join(dir, "work")) -+ opts := indexOff + "lowerdir=" + strings.Join(absLowers, ":") + ",upperdir=" + path.Join(dir, "diff") + ",workdir=" + path.Join(dir, "work") - mountData := label.FormatMountLabel(opts, mountLabel) - mount := unix.Mount - mountTarget := mergedDir -@@ -661,7 +674,7 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e - // fit within a page and relative links make the mount data much - // smaller at the expense of requiring a fork exec to chroot. - if len(mountData) > pageSize { -- opts = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", string(lowers), path.Join(id, "diff"), path.Join(id, "work")) -+ opts = indexOff + "lowerdir=" + string(lowers) + ",upperdir=" + path.Join(id, "diff") + ",workdir=" + path.Join(id, "work") - mountData = label.FormatMountLabel(opts, mountLabel) - if len(mountData) > pageSize { - return nil, fmt.Errorf("cannot mount layer, mount label too large %d", len(mountData)) --- -2.17.1 - diff --git a/patch/0091-overlay2-use-global-logger-instance.patch b/patch/0091-overlay2-use-global-logger-instance.patch deleted file mode 100644 index acdd25f..0000000 --- a/patch/0091-overlay2-use-global-logger-instance.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 7bce81e40dbc73b7e778d8676687efc3b04c6d39 Mon Sep 17 00:00:00 2001 -From: xiadanni -Date: Fri, 1 Feb 2019 01:45:57 +0800 -Subject: [PATCH 091/111] overlay2: use global logger instance - -reason: This simplifies the code a lot. - -Cherry-pick from https://github.com/moby/moby/pull/37993/commits/a55d32546a8556f9e6cabbc99836b573b9944f0c - -Change-Id: I2c4998d677c8500701e077b2520b96fe49ea4364 -Signed-off-by: Kir Kolyshkin -Signed-off-by: xiadanni ---- - .../daemon/graphdriver/overlay2/check.go | 9 ++++----- - .../daemon/graphdriver/overlay2/overlay.go | 20 +++++++++---------- - .../daemon/graphdriver/overlay2/randomid.go | 3 +-- - 3 files changed, 14 insertions(+), 18 deletions(-) - -diff --git a/components/engine/daemon/graphdriver/overlay2/check.go b/components/engine/daemon/graphdriver/overlay2/check.go -index d6ee42f47f..1703b7a00c 100644 ---- a/components/engine/daemon/graphdriver/overlay2/check.go -+++ b/components/engine/daemon/graphdriver/overlay2/check.go -@@ -12,7 +12,6 @@ import ( - - "github.com/docker/docker/pkg/system" - "github.com/pkg/errors" -- "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" - ) - -@@ -27,7 +26,7 @@ func doesSupportNativeDiff(d string) error { - } - defer func() { - if err := os.RemoveAll(td); err != nil { -- logrus.WithField("storage-driver", "overlay2").Warnf("Failed to remove check directory %v: %v", td, err) -+ logger.Warnf("Failed to remove check directory %v: %v", td, err) - } - }() - -@@ -62,7 +61,7 @@ func doesSupportNativeDiff(d string) error { - } - defer func() { - if err := unix.Unmount(filepath.Join(td, "merged"), 0); err != nil { -- logrus.WithField("storage-driver", "overlay2").Warnf("Failed to unmount check directory %v: %v", filepath.Join(td, "merged"), err) -+ logger.Warnf("Failed to unmount check directory %v: %v", filepath.Join(td, "merged"), err) - } - }() - -@@ -113,7 +112,7 @@ func supportsMultipleLowerDir(d string) error { - } - defer func() { - if err := os.RemoveAll(td); err != nil { -- logrus.WithField("storage-driver", "overlay2").Warnf("Failed to remove check directory %v: %v", td, err) -+ logger.Warnf("Failed to remove check directory %v: %v", td, err) - } - }() - -@@ -128,7 +127,7 @@ func supportsMultipleLowerDir(d string) error { - return errors.Wrap(err, "failed to mount overlay") - } - if err := unix.Unmount(filepath.Join(td, "merged"), 0); err != nil { -- logrus.WithField("storage-driver", "overlay2").Warnf("Failed to unmount check directory %v: %v", filepath.Join(td, "merged"), err) -+ logger.Warnf("Failed to unmount check directory %v: %v", filepath.Join(td, "merged"), err) - } - return nil - } -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index d87f979673..71474f8f36 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -106,6 +106,7 @@ type Driver struct { - } - - var ( -+ logger = logrus.WithField("storage-driver", "overlay2") - backingFs = "" - projectQuotaSupported = false - -@@ -157,8 +158,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap - backingFs = fsName - } - -- logger := logrus.WithField("storage-driver", "overlay2") -- - switch fsMagic { - case graphdriver.FsMagicAufs, graphdriver.FsMagicEcryptfs, graphdriver.FsMagicNfsFs, graphdriver.FsMagicOverlay, graphdriver.FsMagicZfs: - logger.Errorf("'overlay2' is not supported over %s", backingFs) -@@ -306,14 +305,14 @@ func supportsOverlay() error { - return nil - } - } -- logrus.WithField("storage-driver", "overlay2").Error("'overlay' not found as a supported filesystem on this host. Please ensure kernel is new enough and has overlay support loaded.") -+ logger.Error("'overlay' not found as a supported filesystem on this host. Please ensure kernel is new enough and has overlay support loaded.") - return graphdriver.ErrNotSupported - } - - func useNaiveDiff(home string) bool { - useNaiveDiffLock.Do(func() { - if err := doesSupportNativeDiff(home); err != nil { -- logrus.WithField("storage-driver", "overlay2").Warnf("Not using native diff for overlay2, this may cause degraded performance for building images: %v", err) -+ logger.Warnf("Not using native diff for overlay2, this may cause degraded performance for building images: %v", err) - useNaiveDiffOnly = true - } - }) -@@ -629,11 +628,11 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e - if retErr != nil { - if c := d.ctr.Decrement(mergedDir); c <= 0 { - if mntErr := unix.Unmount(mergedDir, 0); mntErr != nil { -- logrus.WithField("storage-driver", "overlay2").Errorf("error unmounting %v: %v", mergedDir, mntErr) -+ logger.Errorf("error unmounting %v: %v", mergedDir, mntErr) - } - // Cleanup the created merged directory; see the comment in Put's rmdir - if rmErr := unix.Rmdir(mergedDir); rmErr != nil && !os.IsNotExist(rmErr) { -- logrus.WithField("storage-driver", "overlay2").Debugf("Failed to remove %s: %v: %v", id, rmErr, err) -+ logger.Debugf("Failed to remove %s: %v: %v", id, rmErr, err) - } - } - } -@@ -716,7 +715,6 @@ func (d *Driver) Put(id string) error { - } - - mountpoint := path.Join(dir, "merged") -- logger := logrus.WithField("storage-driver", "overlay2") - if count := d.ctr.Decrement(mountpoint); count > 0 { - return nil - } -@@ -802,7 +800,7 @@ func (d *Driver) ApplyDiff(id string, parent string, diff io.Reader) (size int64 - - applyDir := d.getDiffPath(id) - -- logrus.WithField("storage-driver", "overlay2").Debugf("Applying tar in %s", applyDir) -+ logger.Debugf("Applying tar in %s", applyDir) - // Overlay doesn't need the parent id to apply the diff - if err := untar(diff, applyDir, &archive.TarOptions{ - UIDMaps: d.uidMaps, -@@ -840,7 +838,7 @@ func (d *Driver) Diff(id, parent string) (io.ReadCloser, error) { - } - - diffPath := d.getDiffPath(id) -- logrus.WithField("storage-driver", "overlay2").Debugf("Tar with options on %s", diffPath) -+ logger.Debugf("Tar with options on %s", diffPath) - return archive.TarWithOptions(diffPath, &archive.TarOptions{ - Compression: archive.Uncompressed, - UIDMaps: d.uidMaps, -diff --git a/components/engine/daemon/graphdriver/overlay2/randomid.go b/components/engine/daemon/graphdriver/overlay2/randomid.go -index 933d9fccb6..6ab50df8e6 100644 ---- a/components/engine/daemon/graphdriver/overlay2/randomid.go -+++ b/components/engine/daemon/graphdriver/overlay2/randomid.go -@@ -12,7 +12,6 @@ import ( - "syscall" - "time" - -- "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" - ) - -@@ -48,7 +47,7 @@ func generateID(l int) string { - if retryOnError(err) && retries < maxretries { - count += n - retries++ -- logrus.Errorf("error generating version 4 uuid, retrying: %v", err) -+ logger.Errorf("error generating version 4 uuid, retrying: %v", err) - continue - } - --- -2.17.1 - diff --git a/patch/0092-Revert-docker-Lock-the-RWLayer-while-committi.patch b/patch/0092-Revert-docker-Lock-the-RWLayer-while-committi.patch deleted file mode 100644 index 7713b9c..0000000 --- a/patch/0092-Revert-docker-Lock-the-RWLayer-while-committi.patch +++ /dev/null @@ -1,214 +0,0 @@ -From 5c472ad67723ba45ee92dce62f9f45292213644e Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Fri, 1 Feb 2019 11:02:31 +0800 -Subject: [PATCH 092/111] Revert "docker: Lock the RWLayer while - committing/exporting" - -reason: This reverts commit a3dbaededfff6d20e16740c47ac69de9a91cccff. - -1. rwlayer is already protected by ls.mountL.Lock, no need add lock to -mountedLayer. -2. rwlayer is protected by reference, no need add lock during commit or -export. - -known issues: -- commit or export will put reference during hold lock, if put the last - reference, dead lock happens on release layer. -- delete(docker rm) will set container.RWLayer = nil, it's dangrous - after export or commit when calling container.RWLayer.RUnlockRWLayer(). - -Change-Id: I72cc72a3398133d693cb813fde1964068544ec03 -Signed-off-by: jingrui ---- - components/engine/daemon/commit.go | 2 -- - components/engine/daemon/export.go | 2 -- - components/engine/layer/empty.go | 13 +------------ - components/engine/layer/layer.go | 7 ------- - components/engine/layer/layer_store.go | 4 ---- - components/engine/layer/mounted_layer.go | 10 ---------- - components/engine/layer/ro_layer.go | 10 ---------- - 11 files changed, 7 insertions(+), 53 deletions(-) - -diff --git a/components/engine/daemon/commit.go b/components/engine/daemon/commit.go -index fc7d2782ef..0f6f440514 100644 ---- a/components/engine/daemon/commit.go -+++ b/components/engine/daemon/commit.go -@@ -155,8 +155,6 @@ func (daemon *Daemon) CreateImageFromContainer(name string, c *backend.CreateIma - return "", err - } - -- container.RWLayer.RLockRWLayer() -- defer container.RWLayer.RUnlockRWLayer() - id, err := daemon.imageService.CommitImage(backend.CommitConfig{ - Author: c.Author, - Comment: c.Comment, -diff --git a/components/engine/daemon/export.go b/components/engine/daemon/export.go -index ebd2d75f40..27bc35967d 100644 ---- a/components/engine/daemon/export.go -+++ b/components/engine/daemon/export.go -@@ -34,8 +34,6 @@ func (daemon *Daemon) ContainerExport(name string, out io.Writer) error { - return errdefs.Conflict(err) - } - -- container.RWLayer.RLockRWLayer() -- defer container.RWLayer.RUnlockRWLayer() - data, err := daemon.containerExport(container) - if err != nil { - return fmt.Errorf("Error exporting container %s: %v", name, err) -diff --git a/components/engine/layer/empty.go b/components/engine/layer/empty.go -index 16a49a7abd..c81c702140 100644 ---- a/components/engine/layer/empty.go -+++ b/components/engine/layer/empty.go -@@ -6,16 +6,13 @@ import ( - "fmt" - "io" - "io/ioutil" -- "sync" - ) - - // DigestSHA256EmptyTar is the canonical sha256 digest of empty tar file - - // (1024 NULL bytes) - const DigestSHA256EmptyTar = DiffID("sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef") - --type emptyLayer struct { -- sync.RWMutex --} -+type emptyLayer struct{} - - // EmptyLayer is a layer that corresponds to empty tar. - var EmptyLayer = &emptyLayer{} -@@ -58,14 +55,6 @@ func (el *emptyLayer) Metadata() (map[string]string, error) { - return make(map[string]string), nil - } - --func (el *emptyLayer) RLockRWLayer() { -- el.RLock() --} -- --func (el *emptyLayer) RUnlockRWLayer() { -- el.RUnlock() --} -- - // IsEmpty returns true if the layer is an EmptyLayer - func IsEmpty(diffID DiffID) bool { - return diffID == DigestSHA256EmptyTar -diff --git a/components/engine/layer/layer.go b/components/engine/layer/layer.go -index e35a13135b..cb13c98d0b 100644 ---- a/components/engine/layer/layer.go -+++ b/components/engine/layer/layer.go -@@ -145,13 +145,6 @@ type RWLayer interface { - - // Metadata returns the low level metadata for the mutable layer - Metadata() (map[string]string, error) -- -- // RLockRWLayer locks the RWLayer to block unmounting/removal -- // of that layer -- RLockRWLayer() -- -- // RUnlockRWLayer unlocks the RWLayer -- RUnlockRWLayer() - } - - // Metadata holds information about a -diff --git a/components/engine/layer/layer_store.go b/components/engine/layer/layer_store.go -index 553b098dfd..b6fc45e655 100644 ---- a/components/engine/layer/layer_store.go -+++ b/components/engine/layer/layer_store.go -@@ -598,7 +598,6 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWL - // Release parent chain if error - defer func() { - if err != nil { -- m.Lock() - if deferErr := ls.driver.Remove(m.mountID); deferErr != nil { - logrus.Errorf("Error removing mounted layer during create rw layer %s: %s", m.name, deferErr) - } -@@ -610,7 +609,6 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWL - if deferErr := ls.store.RemoveMount(m.name); deferErr != nil { - logrus.Errorf("Error removing mount metadata during create rw layer %s: %s", m.name, deferErr) - } -- m.Unlock() - - ls.layerL.Lock() - ls.releaseLayer(p) -@@ -688,8 +686,6 @@ func (ls *layerStore) ReleaseRWLayer(l RWLayer) ([]Metadata, error) { - return []Metadata{}, nil - } - -- m.Lock() -- defer m.Unlock() - if err := ls.driver.Remove(m.mountID); err != nil { - logrus.Errorf("Error removing mounted layer %s: %s", m.name, err) - m.retakeReference(l) -diff --git a/components/engine/layer/mounted_layer.go b/components/engine/layer/mounted_layer.go -index 66711d6cf7..d6858c662c 100644 ---- a/components/engine/layer/mounted_layer.go -+++ b/components/engine/layer/mounted_layer.go -@@ -2,7 +2,6 @@ package layer // import "github.com/docker/docker/layer" - - import ( - "io" -- "sync" - - "github.com/docker/docker/pkg/archive" - "github.com/docker/docker/pkg/containerfs" -@@ -17,7 +16,6 @@ type mountedLayer struct { - layerStore *layerStore - - references map[RWLayer]*referencedRWLayer -- sync.RWMutex - } - - func (ml *mountedLayer) cacheParent() string { -@@ -60,14 +58,6 @@ func (ml *mountedLayer) Metadata() (map[string]string, error) { - return ml.layerStore.driver.GetMetadata(ml.mountID) - } - --func (ml *mountedLayer) RLockRWLayer() { -- ml.RLock() --} -- --func (ml *mountedLayer) RUnlockRWLayer() { -- ml.RUnlock() --} -- - func (ml *mountedLayer) getReference() RWLayer { - ref := &referencedRWLayer{ - mountedLayer: ml, -diff --git a/components/engine/layer/ro_layer.go b/components/engine/layer/ro_layer.go -index 59bcf17d18..3555e8b027 100644 ---- a/components/engine/layer/ro_layer.go -+++ b/components/engine/layer/ro_layer.go -@@ -3,7 +3,6 @@ package layer // import "github.com/docker/docker/layer" - import ( - "fmt" - "io" -- "sync" - - "github.com/docker/distribution" - "github.com/opencontainers/go-digest" -@@ -20,7 +19,6 @@ type roLayer struct { - - referenceCount int - references map[Layer]struct{} -- sync.RWMutex - } - - // TarStream for roLayer guarantees that the data that is produced is the exact -@@ -94,14 +92,6 @@ func (rl *roLayer) Metadata() (map[string]string, error) { - return rl.layerStore.driver.GetMetadata(rl.cacheID) - } - --func (rl *roLayer) RLockRWLayer() { -- rl.RLock() --} -- --func (rl *roLayer) RUnlockRWLayer() { -- rl.RUnlock() --} -- - type referencedCacheLayer struct { - *roLayer - } --- -2.17.1 - diff --git a/patch/0093-docker-do-not-try-to-connect-containerd-if-co.patch b/patch/0093-docker-do-not-try-to-connect-containerd-if-co.patch deleted file mode 100644 index 3517793..0000000 --- a/patch/0093-docker-do-not-try-to-connect-containerd-if-co.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 03024503528f2355a666cb37a6b6bc3902bc977d Mon Sep 17 00:00:00 2001 -From: zhangsong34 -Date: Fri, 1 Feb 2019 17:34:44 +0800 -Subject: [PATCH 093/111] docker: do not try to connect containerd if - containerd daemon is down - -reason:do not try to connect containerd if containerd daemon is down, reduce -delay time to restart containerd. - -Change-Id: I7e6ab9e4c154a82b3b2609440cbfc7d3ea14d28d -Signed-off-by: zhangsong34 ---- - components/engine/libcontainerd/supervisor/remote_daemon.go | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/components/engine/libcontainerd/supervisor/remote_daemon.go b/components/engine/libcontainerd/supervisor/remote_daemon.go -index c5da3a56fe..45cc3c3032 100644 ---- a/components/engine/libcontainerd/supervisor/remote_daemon.go -+++ b/components/engine/libcontainerd/supervisor/remote_daemon.go -@@ -289,7 +289,7 @@ func (r *remote) monitorDaemon(ctx context.Context) { - } - } - -- if client != nil { -+ if client != nil && system.IsProcessAlive(r.daemonPid) { - tctx, cancel := context.WithTimeout(ctx, healthCheckTimeout) - _, err := client.IsServing(tctx) - cancel() --- -2.17.1 - diff --git a/patch/0094-docker-change-health-check-minum-param-to-one.patch b/patch/0094-docker-change-health-check-minum-param-to-one.patch deleted file mode 100644 index a493970..0000000 --- a/patch/0094-docker-change-health-check-minum-param-to-one.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 69edbbf9eca76adf67e2b26ee564b53eaef76aff Mon Sep 17 00:00:00 2001 -From: zhangsong34 -Date: Fri, 1 Feb 2019 19:00:14 +0800 -Subject: [PATCH 094/111] docker: change health check minum param to - one second - -reason:change health check minum period to one second, include ---health-interval, --health-timeout and --health-start-period. - -Change-Id: I1ebab75c23edf4f9006142f92894114c5d447f75 -Signed-off-by: zhangsong34 ---- - components/engine/daemon/container.go | 12 ++++++------ - .../engine/integration-cli/docker_api_create_test.go | 7 +++---- - 2 files changed, 9 insertions(+), 10 deletions(-) - -diff --git a/components/engine/daemon/container.go b/components/engine/daemon/container.go -index 06a19bb4c8..6d357421f3 100644 ---- a/components/engine/daemon/container.go -+++ b/components/engine/daemon/container.go -@@ -421,20 +421,20 @@ func (daemon *Daemon) verifyContainerSettings(platform string, hostConfig *conta - - // Validate the healthcheck params of Config - if config.Healthcheck != nil { -- if config.Healthcheck.Interval != 0 && config.Healthcheck.Interval < containertypes.MinimumDuration { -- return nil, errors.Errorf("Interval in Healthcheck cannot be less than %s", containertypes.MinimumDuration) -+ if config.Healthcheck.Interval != 0 && config.Healthcheck.Interval < time.Second { -+ return nil, errors.Errorf("Interval in Healthcheck cannot be less than one second") - } - -- if config.Healthcheck.Timeout != 0 && config.Healthcheck.Timeout < containertypes.MinimumDuration { -- return nil, errors.Errorf("Timeout in Healthcheck cannot be less than %s", containertypes.MinimumDuration) -+ if config.Healthcheck.Timeout != 0 && config.Healthcheck.Timeout < time.Second { -+ return nil, errors.Errorf("Timeout in Healthcheck cannot be less than one second") - } - - if config.Healthcheck.Retries < 0 { - return nil, errors.Errorf("Retries in Healthcheck cannot be negative") - } - -- if config.Healthcheck.StartPeriod != 0 && config.Healthcheck.StartPeriod < containertypes.MinimumDuration { -- return nil, errors.Errorf("StartPeriod in Healthcheck cannot be less than %s", containertypes.MinimumDuration) -+ if config.Healthcheck.StartPeriod != 0 && config.Healthcheck.StartPeriod < time.Second { -+ return nil, errors.Errorf("StartPeriod in Healthcheck cannot be less than one second") - } - } - } -diff --git a/components/engine/integration-cli/docker_api_create_test.go b/components/engine/integration-cli/docker_api_create_test.go -index 8c7fff477e..1bbc7653b3 100644 ---- a/components/engine/integration-cli/docker_api_create_test.go -+++ b/components/engine/integration-cli/docker_api_create_test.go -@@ -5,7 +5,6 @@ import ( - "net/http" - "time" - -- "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/versions" - "github.com/docker/docker/integration-cli/checker" - "github.com/docker/docker/internal/test/request" -@@ -35,7 +34,7 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) { - buf, err := request.ReadBody(body) - c.Assert(err, checker.IsNil) - -- expected := fmt.Sprintf("Interval in Healthcheck cannot be less than %s", container.MinimumDuration) -+ expected := fmt.Sprintf("Interval in Healthcheck cannot be less than one second") - c.Assert(getErrorMessage(c, buf), checker.Contains, expected) - - // test invalid Interval in Healthcheck: larger than 0s but less than 1ms -@@ -82,7 +81,7 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) { - buf, err = request.ReadBody(body) - c.Assert(err, checker.IsNil) - -- expected = fmt.Sprintf("Timeout in Healthcheck cannot be less than %s", container.MinimumDuration) -+ expected = fmt.Sprintf("Timeout in Healthcheck cannot be less than one second") - c.Assert(getErrorMessage(c, buf), checker.Contains, expected) - - // test invalid Retries in Healthcheck: less than 0 -@@ -131,6 +130,6 @@ func (s *DockerSuite) TestAPICreateWithInvalidHealthcheckParams(c *check.C) { - buf, err = request.ReadBody(body) - c.Assert(err, checker.IsNil) - -- expected = fmt.Sprintf("StartPeriod in Healthcheck cannot be less than %s", container.MinimumDuration) -+ expected = fmt.Sprintf("StartPeriod in Healthcheck cannot be less than one second") - c.Assert(getErrorMessage(c, buf), checker.Contains, expected) - } --- -2.17.1 - diff --git a/patch/0095-docker-enable-container-health-check-after-re.patch b/patch/0095-docker-enable-container-health-check-after-re.patch deleted file mode 100644 index 068f4ab..0000000 --- a/patch/0095-docker-enable-container-health-check-after-re.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7f1228356891f66979c7f7e35957ab5392ea8758 Mon Sep 17 00:00:00 2001 -From: zhangsong34 -Date: Fri, 1 Feb 2019 21:18:34 +0800 -Subject: [PATCH 095/111] docker: enable container health check after - restart docker - -reason:enable container health check after restart docker. - -Change-Id: Ic877fdbea8de5b87d2a101c19dbb8a9e8e49c0bb -Signed-off-by: zhangsong34 ---- - components/engine/daemon/daemon.go | 6 +++++- - 5 files changed, 11 insertions(+), 7 deletions(-) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index b207709f7c..f5d22bb18b 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -379,6 +379,10 @@ func (daemon *Daemon) restore() error { - if c.IsRunning() || c.IsPaused() { - c.RestartManager().Cancel() // manually start containers because some need to wait for swarm networking - -+ c.Lock() -+ daemon.initHealthMonitor(c) -+ c.Unlock() -+ - if c.IsPaused() && alive { - s, err := daemon.containerd.Status(context.Background(), c.ID) - if err != nil { -@@ -930,7 +934,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S - - for operatingSystem, gd := range d.graphDrivers { - layerStores[operatingSystem], err = layer.NewStoreFromOptions(layer.StoreOptions{ -- Root: config.Root, -+ Root: config.Root, - MetadataStorePathTemplate: filepath.Join(config.Root, "image", "%s", "layerdb"), - GraphDriver: gd, - GraphDriverOptions: config.GraphOptions, --- -2.17.1 - diff --git a/patch/0096-pause-check-tasks-before-updateCgroups.patch b/patch/0096-pause-check-tasks-before-updateCgroups.patch deleted file mode 100644 index 7d6be96..0000000 --- a/patch/0096-pause-check-tasks-before-updateCgroups.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 086cf3ab125d1c423d07ef877846fd8c1e01f3ac Mon Sep 17 00:00:00 2001 -From: lujingxiao -Date: Mon, 11 Feb 2019 18:44:50 +0800 -Subject: [PATCH 096/111] pause: check tasks before updateCgroups - -reason: In the Pause of dockerd, it updateCgroups first, then -check tasks file if any tasks in the cgroups. We should check the -tasks file before updateCgroups - -Change-Id: I7f30e314b3db9c50459d995bf071e01a47f359f0 -Signed-off-by: lujingxiao ---- - components/engine/daemon/freezer/freezer.go | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - -diff --git a/components/engine/daemon/freezer/freezer.go b/components/engine/daemon/freezer/freezer.go -index cd8b3513d7..a0ef299852 100644 ---- a/components/engine/daemon/freezer/freezer.go -+++ b/components/engine/daemon/freezer/freezer.go -@@ -122,10 +122,6 @@ func (f *freezer) Pause() error { - f.Lock() - defer f.Unlock() - -- if err := f.updateCgroup(string(configs.Frozen)); err != nil { -- return err -- } -- - tasks, err := readFile(f.path, "tasks") - if err != nil { - return fmt.Errorf("failed to check container cgroup task status: %v", err) -@@ -134,7 +130,8 @@ func (f *freezer) Pause() error { - if strings.TrimSpace(tasks) == "" { - return fmt.Errorf("error: no tasks running in freeze cgroup") - } -- return nil -+ -+ return f.updateCgroup(string(configs.Frozen)) - } - - // Resume will set the container to running state by writing freeze cgroup. -@@ -186,7 +183,7 @@ func (f *freezer) updateCgroup(state string) error { - } - newState, err := readFile(f.path, "freezer.state") - if err != nil { -- return err -+ return fmt.Errorf("read freezer.state failed after write: %v", err) - } - if strings.TrimSpace(newState) == state { - return nil --- -2.17.1 - diff --git a/patch/0097-restart-fix-restart-unless-stopped-not-stop-f.patch b/patch/0097-restart-fix-restart-unless-stopped-not-stop-f.patch deleted file mode 100644 index 7194897..0000000 --- a/patch/0097-restart-fix-restart-unless-stopped-not-stop-f.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 8bd08475a06b5475fc88b207d578a006ad9a45cd Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 13 Feb 2019 00:31:32 +0800 -Subject: [PATCH 097/111] restart: fix --restart=unless-stopped not - stop for docker stop - -reason: testCE_secure_container_kata_FUN.054.sh - -Change-Id: I536bb6cf1fe698da9fe330b110f122d4e8af17d6 -Signed-off-by: jingrui ---- - components/engine/daemon/monitor.go | 1 + - components/engine/daemon/start.go | 4 +++- - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/components/engine/daemon/monitor.go b/components/engine/daemon/monitor.go -index 51159eb76d..7ae85f58a9 100644 ---- a/components/engine/daemon/monitor.go -+++ b/components/engine/daemon/monitor.go -@@ -106,6 +106,7 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerd.EventType, ei libc - if err != restartmanager.ErrRestartCanceled { - logrus.Errorf("restartmanger wait error: %+v", err) - } -+ c.CheckpointTo(daemon.containersReplica) - } - }() - } -diff --git a/components/engine/daemon/start.go b/components/engine/daemon/start.go -index 96ae45e11e..8ff636b5a5 100644 ---- a/components/engine/daemon/start.go -+++ b/components/engine/daemon/start.go -@@ -203,7 +203,9 @@ func (daemon *Daemon) containerStart(container *container.Container, checkpoint - } - - container.SetRunning(pid, true) -- container.HasBeenManuallyStopped = false -+ if resetRestartManager { -+ container.HasBeenManuallyStopped = false -+ } - container.HasBeenStartedBefore = true - daemon.setStateCounter(container) - --- -2.17.1 - diff --git a/patch/0099-integration-cli-fix-TestInspectAPIImageRespon.patch b/patch/0099-integration-cli-fix-TestInspectAPIImageRespon.patch deleted file mode 100644 index 5fe9caf..0000000 --- a/patch/0099-integration-cli-fix-TestInspectAPIImageRespon.patch +++ /dev/null @@ -1,30 +0,0 @@ -From b7d540ff87543e02f4d6271afe66edb7aa88477a Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Fri, 15 Feb 2019 15:26:01 +0800 -Subject: [PATCH 099/111] integration-cli: fix - TestInspectAPIImageResponse - -reason:For we tag busybox:glibc before, the tag number will change -in this testcase. So we cancel the action of checking tag number. - -Change-Id: Ib7bf6274d8ca05cc5cbbe3ddd341676b64bb809e -Signed-off-by: zhangyu235 ---- - components/engine/integration-cli/docker_api_inspect_test.go | 1 - - 5 files changed, 6 insertions(+), 7 deletions(-) - -diff --git a/components/engine/integration-cli/docker_api_inspect_test.go b/components/engine/integration-cli/docker_api_inspect_test.go -index 68055b6c14..82d1b19606 100644 ---- a/components/engine/integration-cli/docker_api_inspect_test.go -+++ b/components/engine/integration-cli/docker_api_inspect_test.go -@@ -114,7 +114,6 @@ func (s *DockerSuite) TestInspectAPIImageResponse(c *check.C) { - imageJSON, _, err := cli.ImageInspectWithRaw(context.Background(), "busybox") - c.Assert(err, checker.IsNil) - -- c.Assert(imageJSON.RepoTags, checker.HasLen, 2) - assert.Check(c, is.Contains(imageJSON.RepoTags, "busybox:latest")) - assert.Check(c, is.Contains(imageJSON.RepoTags, "busybox:mytag")) - } --- -2.17.1 - diff --git a/patch/0100-proquota-fix-quota-basesize.patch b/patch/0100-proquota-fix-quota-basesize.patch deleted file mode 100644 index 0c49067..0000000 --- a/patch/0100-proquota-fix-quota-basesize.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 582b84ebefcdd71b963dd431fcf9d1d5f9a20552 Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Mon, 18 Feb 2019 21:23:17 +0800 -Subject: [PATCH 100/111] proquota: fix quota basesize - -reason:fix quota basesize - -Change-Id: I268c600b8c63965daf0086796c48ca4e85263e50 -Signed-off-by: zhangyu235 ---- - components/engine/daemon/graphdriver/overlay2/overlay.go | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index 71474f8f36..1a3c9c9d67 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -89,6 +89,7 @@ const ( - type overlayOptions struct { - overrideKernelCheck bool - quota quota.Quota -+ quotaBaseSize uint64 - } - - // Driver contains information about the home directory and the list of active -@@ -221,6 +222,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap - // Try to enable project quota support over xfs and extfs. - if d.quotaCtl, err = quota.NewControl(home, backingFs); err == nil { - projectQuotaSupported = true -+ d.options.quotaBaseSize = opts.quotaBaseSize - } else if opts.quota.Size > 0 { - return nil, fmt.Errorf("Storage option overlay2.size not supported. Filesystem does not support Project Quota: %v", err) - } -@@ -280,7 +282,7 @@ func parseOptions(options []string) (*overlayOptions, error) { - if err != nil { - return nil, err - } -- o.quota.Size = uint64(size) -+ o.quotaBaseSize = uint64(size) - default: - return nil, fmt.Errorf("overlay2: unknown option %s", key) - } -@@ -422,14 +422,14 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr - } - }() - -- if (opts != nil && len(opts.StorageOpt) > 0) || d.options.quota.Size > 0 { -+ if opts != nil && (len(opts.StorageOpt) > 0 || d.options.quotaBaseSize > 0) { - driver := &Driver{} - if err := d.parseStorageOpt(opts.StorageOpt, driver); err != nil { - return err - } - -- if driver.options.quota.Size == 0 && d.options.quota.Size > 0 { -- driver.options.quota.Size = d.options.quota.Size -+ if driver.options.quota.Size == 0 && d.options.quotaBaseSize > 0 { -+ driver.options.quota.Size = d.options.quotaBaseSize - } - - if driver.options.quota.Size > 0 { --- -2.17.1 - diff --git a/patch/0101-daeamon-add-judge-for-client-in-case-of-panic.patch b/patch/0101-daeamon-add-judge-for-client-in-case-of-panic.patch deleted file mode 100644 index f6987c5..0000000 --- a/patch/0101-daeamon-add-judge-for-client-in-case-of-panic.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 4711c062b0fd8409eef7ed6ed0963b638765cc7f Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Mon, 18 Feb 2019 21:57:38 +0800 -Subject: [PATCH 101/111] daeamon: add judge for client in case of - panic - -reason:Add judge for client in monitorDaemon(), in case of -null ptr error return cause panic. - -Change-Id: Ia0dd64ba0341414d2dbe213a53daa94e2c5d1723 ---- - components/engine/libcontainerd/supervisor/remote_daemon.go | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/components/engine/libcontainerd/supervisor/remote_daemon.go b/components/engine/libcontainerd/supervisor/remote_daemon.go -index 45cc3c3032..62ea58c8b4 100644 ---- a/components/engine/libcontainerd/supervisor/remote_daemon.go -+++ b/components/engine/libcontainerd/supervisor/remote_daemon.go -@@ -318,8 +318,10 @@ func (r *remote) monitorDaemon(ctx context.Context) { - r.killDaemon() - } - -- client.Close() -- client = nil -+ if client != nil { -+ client.Close() -+ client = nil -+ } - r.daemonPid = -1 - delay = nil - transientFailureCount = 0 --- -2.17.1 - diff --git a/patch/0102-docker-18.09-fix-docker-stop-error-if-docker-.patch b/patch/0102-docker-18.09-fix-docker-stop-error-if-docker-.patch deleted file mode 100644 index 638d73e..0000000 --- a/patch/0102-docker-18.09-fix-docker-stop-error-if-docker-.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 40c55ba190f46487686d6131b0005737d8bd06af Mon Sep 17 00:00:00 2001 -From: jiangpengfei9 -Date: Fri, 15 Feb 2019 14:13:47 -0500 -Subject: [PATCH 102/111] docker-18.09: fix docker stop error if docker - has been stopped - -reason: If docker stop send SIGTERM signal to stop container failed, it will wait a short time -and send SIGKILL signal to kill container, but if container has exit while docker stop send -SIGKILL to container, which will cause an error which is "Container %s is not running".So if -docker stop meet this problem, we just let it go and print the warning log. - -Change-Id: Ia832aa93c3a94086849cda70110eb772ac3c0a52 -Signed-off-by: jiangpengfei9 ---- - components/engine/daemon/kill.go | 6 ++++-- - components/engine/daemon/stop.go | 1 + - 6 files changed, 11 insertions(+), 8 deletions(-) - -diff --git a/components/engine/daemon/kill.go b/components/engine/daemon/kill.go -index 5b2e497604..d185065b54 100644 ---- a/components/engine/daemon/kill.go -+++ b/components/engine/daemon/kill.go -@@ -72,7 +72,8 @@ func (daemon *Daemon) killWithSignal(container *containerpkg.Container, sig int) - } - - if !container.Running { -- return errNotRunning(container.ID) -+ logrus.Warnf("killWithSignal skip send kill signal to container %s due to container has been stopped",container.ID) -+ return nil - } - - var unpause bool -@@ -127,7 +128,8 @@ func (daemon *Daemon) killWithSignal(container *containerpkg.Container, sig int) - // Kill forcefully terminates a container. - func (daemon *Daemon) Kill(container *containerpkg.Container) error { - if !container.IsRunning() { -- return errNotRunning(container.ID) -+ logrus.Warnf("Kill skip send kill signal to container %s due to container has been stopped",container.ID) -+ return nil - } - - // 1. Send SIGKILL -diff --git a/components/engine/daemon/stop.go b/components/engine/daemon/stop.go -index c3ac09056a..3c4cd766c9 100644 ---- a/components/engine/daemon/stop.go -+++ b/components/engine/daemon/stop.go -@@ -45,6 +45,7 @@ func (daemon *Daemon) containerStop(container *containerpkg.Container, seconds i - stopSignal := container.StopSignal() - // 1. Send a stop signal - if err := daemon.killPossiblyDeadProcess(container, stopSignal); err != nil { -+ logrus.Infof("docker send %d signal to stop container get error: %v", stopSignal, err) - // While normally we might "return err" here we're not going to - // because if we can't stop the container by this point then - // it's probably because it's already stopped. Meaning, between --- -2.17.1 - diff --git a/patch/0103-docker-fix-parsing-name-with.patch b/patch/0103-docker-fix-parsing-name-with.patch deleted file mode 100644 index c6ff78c..0000000 --- a/patch/0103-docker-fix-parsing-name-with.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 405d10b7df5fa329a7070cb842a8d5e4e46861d6 Mon Sep 17 00:00:00 2001 -From: lixiang172 -Date: Mon, 18 Feb 2019 22:13:53 +0800 -Subject: [PATCH 103/111] docker: fix parsing name with / - -reason: fix parsing name with / -Do the error check when using --link option, -if the alias name and container name is the same, return error - -Change-Id: I64c39915d34d79ee8abbba2ebe0e66ad3ad08551 -Signed-off-by: yangshukui -Signed-off-by: lixiang172 ---- - components/engine/daemon/daemon.go | 13 +++++++++++++ - .../engine/integration-cli/docker_cli_links_test.go | 8 ++++++++ - 2 files changed, 21 insertions(+) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index f5d22bb18b..e26494ed68 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -657,8 +657,21 @@ func (daemon *Daemon) parents(c *container.Container) map[string]*container.Cont - return daemon.linkIndex.parents(c) - } - -+func validateAlias(alias string, c *container.Container) error { -+ if !validContainerNamePattern.MatchString(alias) { -+ return fmt.Errorf("Invalid alias name (%s), only %s are allowed", alias, validContainerNameChars) -+ } -+ if alias == c.Config.Hostname { -+ return fmt.Errorf("Invalid alias name (%s), alias is the same to current container's hostname", alias) -+ } -+ return nil -+} -+ - func (daemon *Daemon) registerLink(parent, child *container.Container, alias string) error { - fullName := path.Join(parent.Name, alias) -+ if err := validateAlias(alias, parent); err != nil { -+ return err -+ } - if err := daemon.containersReplica.ReserveName(fullName, child.ID); err != nil { - if err == container.ErrNameReserved { - logrus.Warnf("error registering link for %s, to %s, as alias %s, ignoring: %v", parent.ID, child.ID, alias, err) -diff --git a/components/engine/integration-cli/docker_cli_links_test.go b/components/engine/integration-cli/docker_cli_links_test.go -index 17b25d7994..9efa1cfbf6 100644 ---- a/components/engine/integration-cli/docker_cli_links_test.go -+++ b/components/engine/integration-cli/docker_cli_links_test.go -@@ -237,3 +237,11 @@ func (s *DockerSuite) TestLinksMultipleWithSameName(c *check.C) { - dockerCmd(c, "run", "-d", "--name=upstream-b", "busybox", "top") - dockerCmd(c, "run", "--link", "upstream-a:upstream", "--link", "upstream-b:upstream", "busybox", "sh", "-c", "ping -c 1 upstream") - } -+func (s *DockerSuite) TestLinksAliasCheck(c *check.C) { -+ testRequires(c, DaemonIsLinux, NotUserNamespace) -+ dockerCmd(c, "run", "-d", "--name=linkalias", "busybox", "top") -+ out, _, _ := dockerCmdWithError("run", "-d", "--link=linkalias:hello/sep", "busybox", "top") -+ c.Assert(out, checker.Contains, "Invalid alias name") -+ out, _, _ = dockerCmdWithError("run", "-d", "--hostname=linkhostname", "--link=linkalias:linkhostname", "busybox", "top") -+ c.Assert(out, checker.Contains, "alias is the same to current container's hostname") -+} --- -2.17.1 - diff --git a/patch/0104-docker-stats-increase-the-timeout-of-docker-s.patch b/patch/0104-docker-stats-increase-the-timeout-of-docker-s.patch deleted file mode 100644 index 4c715b4..0000000 --- a/patch/0104-docker-stats-increase-the-timeout-of-docker-s.patch +++ /dev/null @@ -1,29 +0,0 @@ -From f983b1959dae1d5f0dcae1f7480db5ae69906f74 Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Wed, 20 Feb 2019 11:45:45 +0800 -Subject: [PATCH 104/111] docker stats: increase the timeout of docker - stats command - -reason:Increase the timeout of docker stats command, in case of data lost. - -Change-Id: Ib698f7cfdc06928838b343821a6bdca875327ff7 ---- - components/cli/cli/command/container/stats.go | 2 +- - 5 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/components/cli/cli/command/container/stats.go b/components/cli/cli/command/container/stats.go -index 1f9e1b8556..8387fc988d 100644 ---- a/components/cli/cli/command/container/stats.go -+++ b/components/cli/cli/command/container/stats.go -@@ -172,7 +172,7 @@ func runStats(dockerCli command.Cli, opts *statsOptions) error { - - // Do a quick pause to detect any error with the provided list of - // container names. -- time.Sleep(1500 * time.Millisecond) -+ time.Sleep(2500 * time.Millisecond) - var errs []string - cStats.mu.Lock() - for _, c := range cStats.cs { --- -2.17.1 - diff --git a/patch/0105-pause-fix-pause-on-exited-container.patch b/patch/0105-pause-fix-pause-on-exited-container.patch deleted file mode 100644 index cab75bf..0000000 --- a/patch/0105-pause-fix-pause-on-exited-container.patch +++ /dev/null @@ -1,55 +0,0 @@ -From f66b0742f72a0f15c6b805751c00af2c7b0f3193 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 20 Feb 2019 23:42:00 +0800 -Subject: [PATCH 105/111] pause: fix pause on exited container - -reason: fix pause on exited container - -Change-Id: I109a88ab6832c3118f6be48f5924679549607740 -Signed-off-by: jingrui ---- - components/engine/daemon/freezer/freezer.go | 21 ++++++++++++++++++- - 5 files changed, 26 insertions(+), 7 deletions(-) - -diff --git a/components/engine/daemon/freezer/freezer.go b/components/engine/daemon/freezer/freezer.go -index a0ef299852..907c7aac2a 100644 ---- a/components/engine/daemon/freezer/freezer.go -+++ b/components/engine/daemon/freezer/freezer.go -@@ -12,6 +12,7 @@ import ( - - "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runc/libcontainer/utils" -+ "github.com/sirupsen/logrus" - ) - - // Freezer is the interface which could be used to pause/resume container, -@@ -131,7 +132,25 @@ func (f *freezer) Pause() error { - return fmt.Errorf("error: no tasks running in freeze cgroup") - } - -- return f.updateCgroup(string(configs.Frozen)) -+ err = f.updateCgroup(string(configs.Frozen)) -+ if err != nil { -+ return err -+ } -+ -+ tasks, err = readFile(f.path, "tasks") -+ if err != nil { -+ err := f.updateCgroup(string(configs.Thawed)) -+ logrus.Warnf("revert pause due to no tasks file. revert-error=%v", err) -+ return fmt.Errorf("failed to check container cgroup task status: %v", err) -+ } -+ -+ if strings.TrimSpace(tasks) == "" { -+ err := f.updateCgroup(string(configs.Thawed)) -+ logrus.Warnf("revert pause due to no tasks. revert-error=%v", err) -+ return fmt.Errorf("error: no tasks running in freeze cgroup") -+ } -+ -+ return nil - } - - // Resume will set the container to running state by writing freeze cgroup. --- -2.17.1 - diff --git a/patch/0106-docker-engine-selinux-support-selinux-enabl.patch b/patch/0106-docker-engine-selinux-support-selinux-enabl.patch deleted file mode 100644 index 024ec17..0000000 --- a/patch/0106-docker-engine-selinux-support-selinux-enabl.patch +++ /dev/null @@ -1,2759 +0,0 @@ -From 5c8b4955686c20428b69e5a697a5dc819ff87a43 Mon Sep 17 00:00:00 2001 -From: zhangsong34 -Date: Fri, 22 Feb 2019 17:58:59 +0800 -Subject: [PATCH 106/111] docker-engine-selinux: support - --selinux-enabled=true for daemon - -reason:support --selinux-enabled=true for daemon, fix semodule insert operation -failed. - -Change-Id: Ieaad90896c25aed63767141775f4679c07736430 -Signed-off-by: zhangsong34 ---- - .../docker-engine-selinux/container.fc | 83 ++ - .../docker-engine-selinux/container.if | 713 +++++++++++++ - .../docker-engine-selinux/container.te | 966 ++++++++++++++++++ - .../docker-engine-selinux/docker.fc | 20 - - .../docker-engine-selinux/docker.if | 461 --------- - .../docker-engine-selinux/docker.te | 414 -------- - .../docker-engine-selinux-euleros.spec | 15 +- - 10 files changed, 1777 insertions(+), 903 deletions(-) - create mode 100644 components/engine/contrib/selinux-euleros/docker-engine-selinux/container.fc - create mode 100644 components/engine/contrib/selinux-euleros/docker-engine-selinux/container.if - create mode 100644 components/engine/contrib/selinux-euleros/docker-engine-selinux/container.te - delete mode 100644 components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.fc - delete mode 100644 components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.if - delete mode 100644 components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.te - -diff --git a/components/engine/contrib/selinux-euleros/docker-engine-selinux/container.fc b/components/engine/contrib/selinux-euleros/docker-engine-selinux/container.fc -new file mode 100644 -index 0000000000..0d13c3d1fb ---- /dev/null -+++ b/components/engine/contrib/selinux-euleros/docker-engine-selinux/container.fc -@@ -0,0 +1,83 @@ -+/root/\.docker gen_context(system_u:object_r:container_home_t,s0) -+ -+/usr/libexec/docker/.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/libexec/docker/docker.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/docker.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/lxc-.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/lxd-.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/lxc -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/lxd -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/fuidshift -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/libexec/lxc/.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/libexec/lxd/.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/podman -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/local/bin/podman -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/local/bin/runc -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/runc -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/container[^/]*plugin -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/rhel-push-plugin -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/sbin/rhel-push-plugin -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/docker-latest -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/docker-current -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/docker-novolume-plugin -- gen_context(system_u:object_r:container_auth_exec_t,s0) -+/usr/sbin/crio.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/local/sbin/crio.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/crio.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/local/bin/crio.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/bin/ocid.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/sbin/ocid.* -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+/usr/lib/docker/docker-novolume-plugin -- gen_context(system_u:object_r:container_auth_exec_t,s0) -+/usr/lib/docker/[^/]*plugin -- gen_context(system_u:object_r:container_runtime_exec_t,s0) -+ -+/usr/lib/systemd/system/docker.* -- gen_context(system_u:object_r:container_unit_file_t,s0) -+/usr/lib/systemd/system/lxd.* -- gen_context(system_u:object_r:container_unit_file_t,s0) -+ -+/etc/docker(/.*)? gen_context(system_u:object_r:container_config_t,s0) -+/etc/docker-latest(/.*)? gen_context(system_u:object_r:container_config_t,s0) -+/etc/crio(/.*)? gen_context(system_u:object_r:container_config_t,s0) -+/exports(/.*)? gen_context(system_u:object_r:container_var_lib_t,s0) -+ -+/var/lib/lxc(/.*)? gen_context(system_u:object_r:container_var_lib_t,s0) -+/var/lib/lxd(/.*)? gen_context(system_u:object_r:container_var_lib_t,s0) -+/var/lib/docker(/.*)? gen_context(system_u:object_r:container_var_lib_t,s0) -+/var/lib/docker/.*/config\.env gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/docker/containers/.*/.*\.log gen_context(system_u:object_r:container_log_t,s0) -+/var/lib/docker/containers/.*/hostname gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/docker/containers/.*/hosts gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/docker/init(/.*)? gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/docker/overlay(/.*)? gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/docker/overlay2(/.*)? gen_context(system_u:object_r:container_share_t,s0) -+ -+/var/lib/containers(/.*)? gen_context(system_u:object_r:container_var_lib_t,s0) -+/var/lib/containers/overlay(/.*)? gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/containers/overlay2(/.*)? gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/containers/atomic(/.*)? <> -+/var/lib/containers/storage/overlay(/.*)? gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/containers/storage/overlay2(/.*)? gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/ocid(/.*)? gen_context(system_u:object_r:container_var_lib_t,s0) -+/var/lib/ocid/sandboxes(/.*)? gen_context(system_u:object_r:container_share_t,s0) -+ -+/var/lib/origin(/.*)? gen_context(system_u:object_r:container_file_t,s0) -+ -+/var/lib/docker-latest(/.*)? gen_context(system_u:object_r:container_var_lib_t,s0) -+/var/lib/docker-latest/.*/config\.env gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/docker-latest/containers/.*/.*\.log gen_context(system_u:object_r:container_log_t,s0) -+/var/lib/docker-latest/containers/.*/hostname gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/docker-latest/containers/.*/hosts gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/docker-latest/init(/.*)? gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/docker-latest/overlay(/.*)? gen_context(system_u:object_r:container_share_t,s0) -+/var/lib/docker-latest/overlay2(/.*)? gen_context(system_u:object_r:container_share_t,s0) -+ -+/var/run/containers(/.*)? gen_context(system_u:object_r:container_var_run_t,s0) -+/var/run/crio(/.*)? gen_context(system_u:object_r:container_var_run_t,s0) -+/var/run/docker(/.*)? gen_context(system_u:object_r:container_var_run_t,s0) -+/var/run/containerd(/.*)? gen_context(system_u:object_r:container_var_run_t,s0) -+/var/run/docker\.pid -- gen_context(system_u:object_r:container_var_run_t,s0) -+/var/run/docker\.sock -s gen_context(system_u:object_r:container_var_run_t,s0) -+/var/run/docker-client(/.*)? gen_context(system_u:object_r:container_var_run_t,s0) -+/var/run/docker/plugins(/.*)? gen_context(system_u:object_r:container_plugin_var_run_t,s0) -+ -+/var/lock/lxc(/.*)? gen_context(system_u:object_r:container_lock_t,s0) -+ -+/var/log/lxc(/.*)? gen_context(system_u:object_r:container_log_t,s0) -+/var/log/lxd(/.*)? gen_context(system_u:object_r:container_log_t,s0) -diff --git a/components/engine/contrib/selinux-euleros/docker-engine-selinux/container.if b/components/engine/contrib/selinux-euleros/docker-engine-selinux/container.if -new file mode 100644 -index 0000000000..3853ca5bde ---- /dev/null -+++ b/components/engine/contrib/selinux-euleros/docker-engine-selinux/container.if -@@ -0,0 +1,713 @@ -+ -+## The open-source application container engine. -+ -+######################################## -+## -+## Execute container in the container domain. -+## -+## -+## -+## Domain allowed to transition. -+## -+## -+# -+interface(`container_runtime_domtrans',` -+ gen_require(` -+ type container_runtime_t, container_runtime_exec_t; -+ type container_runtime_tmpfs_t; -+ ') -+ -+ corecmd_search_bin($1) -+ domtrans_pattern($1, container_runtime_exec_t, container_runtime_t) -+') -+ -+######################################## -+## -+## Execute container runtime in the congtainer runtime domain -+## -+## -+## -+## Domain allowed to transition. -+## -+## -+## -+## -+## Role allowed access. -+## -+## -+## -+# -+interface(`container_runtime_run',` -+ gen_require(` -+ type container_runtime_t; -+ ') -+ -+ container_domtrans($1) -+ roleattribute $2 container_runtime_t; -+') -+ -+ -+######################################## -+## -+## Execute container in the caller domain. -+## -+## -+## -+## Domain allowed to transition. -+## -+## -+# -+interface(`container_runtime_exec',` -+ gen_require(` -+ type container_runtime_exec_t; -+ ') -+ -+ corecmd_search_bin($1) -+ can_exec($1, container_runtime_exec_t) -+') -+ -+######################################## -+## -+## Read the process state of container runtime -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_read_state',` -+ gen_require(` -+ type container_runtime_t; -+ ') -+ -+ ps_process_pattern($1, container_runtime_t) -+') -+ -+######################################## -+## -+## Search container lib directories. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_search_lib',` -+ gen_require(` -+ type container_var_lib_t; -+ ') -+ -+ allow $1 container_var_lib_t:dir search_dir_perms; -+ files_search_var_lib($1) -+') -+ -+######################################## -+## -+## Execute container lib directories. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_exec_lib',` -+ gen_require(` -+ type container_var_lib_t; -+ ') -+ -+ allow $1 container_var_lib_t:dir search_dir_perms; -+ can_exec($1, container_var_lib_t) -+') -+ -+######################################## -+## -+## Read container lib files. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_read_lib_files',` -+ gen_require(` -+ type container_var_lib_t; -+ ') -+ -+ files_search_var_lib($1) -+ read_files_pattern($1, container_var_lib_t, container_var_lib_t) -+') -+ -+######################################## -+## -+## Read container share files. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_read_share_files',` -+ gen_require(` -+ type container_share_t; -+ ') -+ -+ files_search_var_lib($1) -+ list_dirs_pattern($1, container_share_t, container_share_t) -+ read_files_pattern($1, container_share_t, container_share_t) -+ read_lnk_files_pattern($1, container_share_t, container_share_t) -+') -+ -+###################################### -+## -+## Allow the specified domain to execute container shared files -+## in the caller domain. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_exec_share_files',` -+ gen_require(` -+ type container_share_t; -+ ') -+ -+ can_exec($1, container_share_t) -+') -+ -+######################################## -+## -+## Manage container lib files. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_manage_lib_files',` -+ gen_require(` -+ type container_var_lib_t; -+ ') -+ -+ files_search_var_lib($1) -+ manage_files_pattern($1, container_var_lib_t, container_var_lib_t) -+ manage_lnk_files_pattern($1, container_var_lib_t, container_var_lib_t) -+') -+ -+######################################## -+## -+## Manage container files. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_manage_files',` -+ gen_require(` -+ type container_files_t; -+ ') -+ -+ manage_files_pattern($1, container_files_t, container_files_t) -+ manage_lnk_files_pattern($1, container_files_t, container_files_t) -+') -+ -+######################################## -+## -+## Manage container directories. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_manage_dirs',` -+ gen_require(` -+ type container_files_t; -+ ') -+ -+ manage_dirs_pattern($1, container_files_t, container_files_t) -+') -+ -+######################################## -+## -+## Manage container lib directories. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_manage_lib_dirs',` -+ gen_require(` -+ type container_var_lib_t; -+ ') -+ -+ files_search_var_lib($1) -+ manage_dirs_pattern($1, container_var_lib_t, container_var_lib_t) -+') -+ -+######################################## -+## -+## Create objects in a container var lib directory -+## with an automatic type transition to -+## a specified private type. -+## -+## -+## -+## Domain allowed access. -+## -+## -+## -+## -+## The type of the object to create. -+## -+## -+## -+## -+## The class of the object to be created. -+## -+## -+## -+## -+## The name of the object being created. -+## -+## -+# -+interface(`container_lib_filetrans',` -+ gen_require(` -+ type container_var_lib_t; -+ ') -+ -+ filetrans_pattern($1, container_var_lib_t, $2, $3, $4) -+') -+ -+######################################## -+## -+## Read container PID files. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_read_pid_files',` -+ gen_require(` -+ type container_var_run_t; -+ ') -+ -+ files_search_pids($1) -+ read_files_pattern($1, container_var_run_t, container_var_run_t) -+') -+ -+######################################## -+## -+## Execute container server in the container domain. -+## -+## -+## -+## Domain allowed to transition. -+## -+## -+# -+interface(`container_systemctl',` -+ gen_require(` -+ type container_runtime_t; -+ type container_unit_file_t; -+ ') -+ -+ systemd_exec_systemctl($1) -+ init_reload_services($1) -+ systemd_read_fifo_file_passwd_run($1) -+ allow $1 container_unit_file_t:file read_file_perms; -+ allow $1 container_unit_file_t:service manage_service_perms; -+ -+ ps_process_pattern($1, container_runtime_t) -+') -+ -+######################################## -+## -+## Read and write container shared memory. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_rw_sem',` -+ gen_require(` -+ type container_runtime_t; -+ ') -+ -+ allow $1 container_runtime_t:sem rw_sem_perms; -+') -+ -+####################################### -+## -+## Read and write the container pty type. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_use_ptys',` -+ gen_require(` -+ type container_devpts_t; -+ ') -+ -+ allow $1 container_devpts_t:chr_file rw_term_perms; -+') -+ -+####################################### -+## -+## Allow domain to create container content -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_filetrans_named_content',` -+ -+ gen_require(` -+ type container_var_lib_t; -+ type container_share_t; -+ type container_log_t; -+ type container_var_run_t; -+ type container_home_t; -+ ') -+ -+ files_pid_filetrans($1, container_var_run_t, file, "container.pid") -+ files_pid_filetrans($1, container_var_run_t, file, "docker.pid") -+ files_pid_filetrans($1, container_var_run_t, sock_file, "container.sock") -+ files_pid_filetrans($1, container_var_run_t, dir, "container-client") -+ files_pid_filetrans($1, container_var_run_t, dir, "docker") -+ files_pid_filetrans($1, container_var_run_t, dir, "containerd") -+ files_pid_filetrans($1, container_var_run_t, dir, "ocid") -+ files_pid_filetrans($1, container_var_run_t, dir, "containers") -+ logging_log_filetrans($1, container_log_t, dir, "lxc") -+ files_var_lib_filetrans($1, container_var_lib_t, dir, "containers") -+ files_var_lib_filetrans($1, container_file_t, dir, "origin") -+ files_var_lib_filetrans($1, container_var_lib_t, dir, "ocid") -+ files_var_lib_filetrans($1, container_var_lib_t, dir, "docker") -+ files_var_lib_filetrans($1, container_var_lib_t, dir, "docker-latest") -+ filetrans_pattern($1, container_var_lib_t, container_share_t, file, "config.env") -+ filetrans_pattern($1, container_var_lib_t, container_share_t, file, "hosts") -+ filetrans_pattern($1, container_var_lib_t, container_share_t, file, "hostname") -+ filetrans_pattern($1, container_var_lib_t, container_share_t, file, "resolv.conf") -+ filetrans_pattern($1, container_var_lib_t, container_share_t, dir, "sandboxes") -+ filetrans_pattern($1, container_var_lib_t, container_share_t, dir, "init") -+ filetrans_pattern($1, container_var_lib_t, container_share_t, dir, "overlay") -+ filetrans_pattern($1, container_var_lib_t, container_share_t, dir, "overlay2") -+ filetrans_pattern($1, container_var_lib_t, container_share_t, dir, "atomic") -+ userdom_admin_home_dir_filetrans($1, container_home_t, dir, ".container") -+ -+') -+ -+######################################## -+## -+## Connect to container over a unix stream socket. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_stream_connect',` -+ gen_require(` -+ type container_runtime_t, container_var_run_t, container_runtime_tmpfs_t; -+ ') -+ -+ files_search_pids($1) -+ stream_connect_pattern($1, container_var_run_t, container_var_run_t, container_runtime_t) -+ stream_connect_pattern($1, container_runtime_tmpfs_t, container_runtime_tmpfs_t, container_runtime_t) -+ allow $1 container_runtime_tmpfs_t:lnk_file read_lnk_file_perms; -+') -+ -+######################################## -+## -+## Connect to SPC containers over a unix stream socket. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_spc_stream_connect',` -+ gen_require(` -+ type spc_t, spc_var_run_t; -+ ') -+ -+ files_search_pids($1) -+ files_write_all_pid_sockets($1) -+ allow $1 spc_t:unix_stream_socket connectto; -+') -+ -+######################################## -+## -+## All of the rules required to administrate -+## an container environment -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_admin',` -+ gen_require(` -+ type container_runtime_t; -+ type container_var_lib_t, container_var_run_t; -+ type container_unit_file_t; -+ type container_lock_t; -+ type container_log_t; -+ type container_config_t; -+ ') -+ -+ allow $1 container_runtime_t:process { ptrace signal_perms }; -+ ps_process_pattern($1, container_runtime_t) -+ -+ admin_pattern($1, container_config_t) -+ -+ files_search_var_lib($1) -+ admin_pattern($1, container_var_lib_t) -+ -+ files_search_pids($1) -+ admin_pattern($1, container_var_run_t) -+ -+ files_search_locks($1) -+ admin_pattern($1, container_lock_t) -+ -+ logging_search_logs($1) -+ admin_pattern($1, container_log_t) -+ -+ container_systemctl($1) -+ admin_pattern($1, container_unit_file_t) -+ allow $1 container_unit_file_t:service all_service_perms; -+ -+ optional_policy(` -+ systemd_passwd_agent_exec($1) -+ systemd_read_fifo_file_passwd_run($1) -+ ') -+') -+ -+######################################## -+## -+## Execute container_auth_exec_t in the container_auth domain. -+## -+## -+## -+## Domain allowed to transition. -+## -+## -+# -+interface(`container_auth_domtrans',` -+ gen_require(` -+ type container_auth_t, container_auth_exec_t; -+ ') -+ -+ corecmd_search_bin($1) -+ domtrans_pattern($1, container_auth_exec_t, container_auth_t) -+') -+ -+###################################### -+## -+## Execute container_auth in the caller domain. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_auth_exec',` -+ gen_require(` -+ type container_auth_exec_t; -+ ') -+ -+ corecmd_search_bin($1) -+ can_exec($1, container_auth_exec_t) -+') -+ -+######################################## -+## -+## Connect to container_auth over a unix stream socket. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_auth_stream_connect',` -+ gen_require(` -+ type container_auth_t, container_plugin_var_run_t; -+ ') -+ -+ files_search_pids($1) -+ stream_connect_pattern($1, container_plugin_var_run_t, container_plugin_var_run_t, container_auth_t) -+') -+ -+######################################## -+## -+## container domain typebounds calling domain. -+## -+## -+## -+## Domain to be typebound. -+## -+## -+# -+interface(`container_runtime_typebounds',` -+ gen_require(` -+ type container_runtime_t; -+ ') -+ -+ allow container_runtime_t $1:process2 nnp_transition; -+') -+ -+######################################## -+## -+## Allow any container_runtime_exec_t to be an entrypoint of this domain -+## -+## -+## -+## Domain allowed access. -+## -+## -+## -+# -+interface(`container_runtime_entrypoint',` -+ gen_require(` -+ type container_runtime_exec_t; -+ ') -+ allow $1 container_runtime_exec_t:file entrypoint; -+') -+ -+interface(`docker_exec_lib',` -+ container_exec_lib($1) -+') -+ -+interface(`docker_read_share_files',` -+ container_read_share_files($1) -+') -+ -+interface(`docker_exec_share_files',` -+ container_exec_share_files($1) -+') -+ -+interface(`docker_manage_lib_files',` -+ container_manage_lib_files($1) -+') -+ -+ -+interface(`docker_manage_lib_dirs',` -+ container_manage_lib_dirs($1) -+') -+ -+interface(`docker_lib_filetrans',` -+ container_lib_filetrans($1, $2, $3, $4) -+') -+ -+interface(`docker_read_pid_files',` -+ container_read_pid_files($1) -+') -+ -+interface(`docker_systemctl',` -+ container_systemctl($1) -+') -+ -+interface(`docker_use_ptys',` -+ container_use_ptys($1) -+') -+ -+interface(`docker_stream_connect',` -+ container_stream_connect($1) -+') -+ -+interface(`docker_spc_stream_connect',` -+ container_spc_stream_connect($1) -+') -+ -+######################################## -+## -+## Read the process state of spc containers -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_spc_read_state',` -+ gen_require(` -+ type spc_t; -+ ') -+ -+ ps_process_pattern($1, spc_t) -+') -+ -+######################################## -+## -+## Creates types and rules for a basic -+## container process domain. -+## -+## -+## -+## Prefix for the domain. -+## -+## -+# -+template(`container_domain_template',` -+ gen_require(` -+ attribute container_domain; -+ type container_runtime_t; -+ type container_var_lib_t; -+ type container_share_t; -+ ') -+ -+ type $1_t, container_domain; -+ domain_type($1_t) -+ domain_user_exemption_target($1_t) -+ mls_rangetrans_target($1_t) -+ mcs_constrained($1_t) -+ role system_r types $1_t; -+ allow $1_t { container_var_lib_t container_share_t }:file entrypoint; -+ -+ kernel_read_all_proc($1_t) -+') -+ -+######################################## -+## -+## Read and write a spc_t unnamed pipe. -+## -+## -+## -+## Domain allowed access. -+## -+## -+# -+interface(`container_spc_rw_pipes',` -+ gen_require(` -+ type spc_t; -+ ') -+ -+ allow $1 spc_t:fifo_file rw_inherited_fifo_file_perms; -+') -diff --git a/components/engine/contrib/selinux-euleros/docker-engine-selinux/container.te b/components/engine/contrib/selinux-euleros/docker-engine-selinux/container.te -new file mode 100644 -index 0000000000..14bd4f38d6 ---- /dev/null -+++ b/components/engine/contrib/selinux-euleros/docker-engine-selinux/container.te -@@ -0,0 +1,966 @@ -+policy_module(container, 2.68.0) -+gen_require(` -+ class passwd rootok; -+ type container_file_t; -+') -+ -+######################################## -+# -+# Declarations -+# -+ -+## -+##

-+## Determine whether container can -+## connect to all TCP ports. -+##

-+##
-+gen_tunable(container_connect_any, false) -+ -+## -+##

-+## Allow sandbox containers to manage cgroup (systemd) -+##

-+##
-+gen_tunable(container_manage_cgroup, false) -+ -+type container_runtime_t alias docker_t; -+type container_runtime_exec_t alias docker_exec_t; -+init_daemon_domain(container_runtime_t, container_runtime_exec_t) -+domain_subj_id_change_exemption(container_runtime_t) -+domain_role_change_exemption(container_runtime_t) -+can_exec(container_runtime_t,container_runtime_exec_t) -+attribute container_domain; -+attribute container_net_domain; -+allow container_runtime_t container_domain:process transition; -+allow container_runtime_t container_domain:process2 { nnp_transition nosuid_transition }; -+ -+type spc_t; -+domain_type(spc_t) -+role system_r types spc_t; -+ -+type container_auth_t alias docker_auth_t; -+type container_auth_exec_t alias docker_auth_exec_t; -+init_daemon_domain(container_auth_t, container_auth_exec_t) -+ -+type spc_var_run_t; -+files_pid_file(spc_var_run_t) -+ -+type container_var_lib_t alias docker_var_lib_t; -+files_type(container_var_lib_t) -+ -+type container_home_t alias docker_home_t; -+userdom_user_home_content(container_home_t) -+ -+type container_config_t alias docker_config_t; -+files_config_file(container_config_t) -+ -+type container_lock_t alias docker_lock_t; -+files_lock_file(container_lock_t) -+ -+type container_log_t alias docker_log_t; -+logging_log_file(container_log_t) -+ -+type container_runtime_tmp_t alias docker_tmp_t; -+files_tmp_file(container_runtime_tmp_t) -+ -+type container_runtime_tmpfs_t alias docker_tmpfs_t; -+files_tmpfs_file(container_runtime_tmpfs_t) -+ -+type container_var_run_t alias docker_var_run_t; -+files_pid_file(container_var_run_t) -+ -+type container_plugin_var_run_t alias docker_plugin_var_run_t; -+files_pid_file(container_plugin_var_run_t) -+ -+type container_unit_file_t alias docker_unit_file_t; -+systemd_unit_file(container_unit_file_t) -+ -+type container_devpts_t alias docker_devpts_t; -+term_pty(container_devpts_t) -+ -+type container_share_t alias docker_share_t; -+files_mountpoint(container_share_t) -+ -+type container_port_t alias docker_port_t; -+corenet_port(container_port_t) -+ -+#ifdef(`enable_mcs',` -+# init_ranged_daemon_domain(container_runtime_t, container_runtime_exec_t, s0 - mcs_systemhigh) -+#') -+ -+ifdef(`enable_mls',` -+ init_ranged_daemon_domain(container_runtime_t, container_runtime_exec_t, s0 - mls_systemhigh) -+') -+ -+######################################## -+# -+# container local policy -+# -+allow container_runtime_t self:capability { chown kill fowner fsetid mknod net_admin net_bind_service net_raw setfcap sys_resource }; -+allow container_runtime_t self:tun_socket { create_socket_perms relabelto }; -+allow container_runtime_t self:process ~setcurrent; -+allow container_runtime_t self:passwd rootok; -+allow container_runtime_t self:fd use; -+allow container_runtime_t self:file mounton; -+ -+allow container_runtime_t self:fifo_file rw_fifo_file_perms; -+allow container_runtime_t self:fifo_file manage_file_perms; -+allow container_runtime_t self:msg all_msg_perms; -+allow container_runtime_t self:sem create_sem_perms; -+allow container_runtime_t self:shm create_shm_perms; -+allow container_runtime_t self:msgq create_msgq_perms; -+allow container_runtime_t self:unix_stream_socket create_stream_socket_perms; -+allow container_runtime_t self:tcp_socket create_stream_socket_perms; -+allow container_runtime_t self:udp_socket create_socket_perms; -+allow container_runtime_t self:capability2 block_suspend; -+allow container_runtime_t container_port_t:tcp_socket name_bind; -+allow container_runtime_t self:filesystem associate; -+allow container_runtime_t self:packet_socket create_socket_perms; -+allow container_runtime_t self:socket create_socket_perms; -+allow container_runtime_t self:rawip_socket create_stream_socket_perms; -+allow container_runtime_t self:netlink_netfilter_socket create_socket_perms; -+allow container_runtime_t self:netlink_kobject_uevent_socket create_socket_perms; -+allow container_runtime_t self:netlink_tcpdiag_socket create_netlink_socket_perms; -+allow container_runtime_t self:netlink_socket create_socket_perms; -+ -+corenet_tcp_bind_generic_node(container_runtime_t) -+corenet_udp_bind_generic_node(container_runtime_t) -+corenet_raw_bind_generic_node(container_runtime_t) -+corenet_tcp_sendrecv_all_ports(container_runtime_t) -+corenet_udp_sendrecv_all_ports(container_runtime_t) -+corenet_udp_bind_all_ports(container_runtime_t) -+corenet_tcp_bind_all_ports(container_runtime_t) -+corenet_tcp_connect_all_ports(container_runtime_t) -+ -+mls_file_read_to_clearance(container_runtime_t) -+mls_file_write_to_clearance(container_runtime_t) -+ -+container_auth_stream_connect(container_runtime_t) -+ -+manage_blk_files_pattern(container_runtime_t, container_file_t, container_file_t) -+manage_sock_files_pattern(container_runtime_t, container_file_t, container_file_t) -+allow container_runtime_t container_file_t:dir {relabelfrom relabelto execmod}; -+allow container_runtime_t container_file_t:chr_file mmap_file_perms; -+ -+manage_files_pattern(container_runtime_t, container_home_t, container_home_t) -+manage_dirs_pattern(container_runtime_t, container_home_t, container_home_t) -+manage_lnk_files_pattern(container_runtime_t, container_home_t, container_home_t) -+userdom_admin_home_dir_filetrans(container_runtime_t, container_home_t, dir, ".container") -+userdom_manage_user_home_content(container_runtime_t) -+ -+manage_dirs_pattern(container_runtime_t, container_config_t, container_config_t) -+manage_files_pattern(container_runtime_t, container_config_t, container_config_t) -+files_etc_filetrans(container_runtime_t, container_config_t, dir, "container") -+ -+manage_dirs_pattern(container_runtime_t, container_lock_t, container_lock_t) -+manage_files_pattern(container_runtime_t, container_lock_t, container_lock_t) -+files_lock_filetrans(container_runtime_t, container_lock_t, { dir file }, "lxc") -+ -+manage_dirs_pattern(container_runtime_t, container_log_t, container_log_t) -+manage_files_pattern(container_runtime_t, container_log_t, container_log_t) -+manage_lnk_files_pattern(container_runtime_t, container_log_t, container_log_t) -+logging_log_filetrans(container_runtime_t, container_log_t, { dir file lnk_file }) -+allow container_runtime_t container_log_t:dir_file_class_set { relabelfrom relabelto }; -+filetrans_pattern(container_runtime_t, container_var_lib_t, container_log_t, file, "container-json.log") -+allow container_runtime_t { container_var_lib_t container_share_t }:file entrypoint; -+ -+manage_dirs_pattern(container_runtime_t, container_runtime_tmp_t, container_runtime_tmp_t) -+manage_files_pattern(container_runtime_t, container_runtime_tmp_t, container_runtime_tmp_t) -+manage_sock_files_pattern(container_runtime_t, container_runtime_tmp_t, container_runtime_tmp_t) -+manage_lnk_files_pattern(container_runtime_t, container_runtime_tmp_t, container_runtime_tmp_t) -+files_tmp_filetrans(container_runtime_t, container_runtime_tmp_t, { dir file lnk_file }) -+ -+manage_dirs_pattern(container_runtime_t, container_runtime_tmpfs_t, container_runtime_tmpfs_t) -+manage_files_pattern(container_runtime_t, container_runtime_tmpfs_t, container_runtime_tmpfs_t) -+manage_lnk_files_pattern(container_runtime_t, container_runtime_tmpfs_t, container_runtime_tmpfs_t) -+manage_fifo_files_pattern(container_runtime_t, container_runtime_tmpfs_t, container_runtime_tmpfs_t) -+manage_chr_files_pattern(container_runtime_t, container_runtime_tmpfs_t, container_runtime_tmpfs_t) -+manage_blk_files_pattern(container_runtime_t, container_runtime_tmpfs_t, container_runtime_tmpfs_t) -+allow container_runtime_t container_runtime_tmpfs_t:dir relabelfrom; -+can_exec(container_runtime_t, container_runtime_tmpfs_t) -+fs_tmpfs_filetrans(container_runtime_t, container_runtime_tmpfs_t, { dir file }) -+allow container_runtime_t container_runtime_tmpfs_t:chr_file mounton; -+ -+manage_dirs_pattern(container_runtime_t, container_share_t, container_share_t) -+manage_chr_files_pattern(container_runtime_t, container_share_t, container_share_t) -+manage_blk_files_pattern(container_runtime_t, container_share_t, container_share_t) -+manage_files_pattern(container_runtime_t, container_share_t, container_share_t) -+manage_lnk_files_pattern(container_runtime_t, container_share_t, container_share_t) -+allow container_runtime_t container_share_t:dir_file_class_set { relabelfrom relabelto }; -+can_exec(container_runtime_t, container_share_t) -+filetrans_pattern(container_runtime_t, container_var_lib_t, container_share_t, dir, "init") -+filetrans_pattern(container_runtime_t, container_var_lib_t, container_share_t, dir, "overlay") -+filetrans_pattern(container_runtime_t, container_var_lib_t, container_share_t, dir, "overlay2") -+filetrans_pattern(container_runtime_t, container_var_lib_t, container_share_t, file, "config.env") -+filetrans_pattern(container_runtime_t, container_var_lib_t, container_share_t, file, "hostname") -+filetrans_pattern(container_runtime_t, container_var_lib_t, container_share_t, file, "hosts") -+ -+#container_filetrans_named_content(container_runtime_t) -+ -+manage_dirs_pattern(container_runtime_t, container_var_lib_t, container_var_lib_t) -+manage_files_pattern(container_runtime_t, container_var_lib_t, container_var_lib_t) -+manage_chr_files_pattern(container_runtime_t, container_var_lib_t, container_var_lib_t) -+manage_blk_files_pattern(container_runtime_t, container_var_lib_t, container_var_lib_t) -+manage_sock_files_pattern(container_runtime_t, container_var_lib_t, container_var_lib_t) -+manage_lnk_files_pattern(container_runtime_t, container_var_lib_t, container_var_lib_t) -+allow container_runtime_t container_var_lib_t:dir_file_class_set { relabelfrom relabelto }; -+files_var_lib_filetrans(container_runtime_t, container_var_lib_t, { dir file lnk_file }) -+ -+manage_dirs_pattern(container_runtime_t, container_var_run_t, container_var_run_t) -+manage_files_pattern(container_runtime_t, container_var_run_t, container_var_run_t) -+manage_fifo_files_pattern(container_runtime_t, container_var_run_t, container_var_run_t) -+manage_sock_files_pattern(container_runtime_t, container_var_run_t, container_var_run_t) -+manage_lnk_files_pattern(container_runtime_t, container_var_run_t, container_var_run_t) -+files_pid_filetrans(container_runtime_t, container_var_run_t, { dir file lnk_file sock_file }) -+ -+allow container_runtime_t container_devpts_t:chr_file { relabelfrom rw_chr_file_perms setattr_chr_file_perms }; -+term_create_pty(container_runtime_t, container_devpts_t) -+term_use_all_ttys(container_runtime_t) -+term_use_all_inherited_terms(container_runtime_t) -+ -+kernel_read_system_state(container_runtime_t) -+kernel_read_network_state(container_runtime_t) -+kernel_read_all_sysctls(container_runtime_t) -+kernel_rw_net_sysctls(container_runtime_t) -+kernel_setsched(container_runtime_t) -+kernel_read_all_proc(container_runtime_t) -+kernel_rw_all_sysctls(container_runtime_t) -+ -+domain_use_interactive_fds(container_runtime_t) -+domain_dontaudit_read_all_domains_state(container_runtime_t) -+domain_sigchld_all_domains(container_runtime_t) -+domain_use_interactive_fds(container_runtime_t) -+domain_read_all_domains_state(container_runtime_t) -+domain_getattr_all_domains(container_runtime_t) -+ -+gen_require(` -+ attribute domain; -+') -+ -+allow container_runtime_t domain:fifo_file rw_fifo_file_perms; -+allow container_runtime_t domain:fd use; -+ -+corecmd_exec_bin(container_runtime_t) -+corecmd_exec_shell(container_runtime_t) -+corecmd_exec_all_executables(container_runtime_t) -+corecmd_bin_entry_type(container_runtime_t) -+corecmd_shell_entry_type(container_runtime_t) -+ -+corenet_tcp_bind_generic_node(container_runtime_t) -+corenet_tcp_sendrecv_generic_if(container_runtime_t) -+corenet_tcp_sendrecv_generic_node(container_runtime_t) -+corenet_tcp_sendrecv_generic_port(container_runtime_t) -+corenet_tcp_bind_all_ports(container_runtime_t) -+corenet_tcp_connect_http_port(container_runtime_t) -+corenet_tcp_connect_commplex_main_port(container_runtime_t) -+corenet_udp_sendrecv_generic_if(container_runtime_t) -+corenet_udp_sendrecv_generic_node(container_runtime_t) -+corenet_udp_sendrecv_all_ports(container_runtime_t) -+corenet_udp_bind_generic_node(container_runtime_t) -+corenet_udp_bind_all_ports(container_runtime_t) -+ -+files_read_kernel_modules(container_runtime_t) -+files_read_config_files(container_runtime_t) -+files_dontaudit_getattr_all_dirs(container_runtime_t) -+files_dontaudit_getattr_all_files(container_runtime_t) -+files_execmod_all_files(container_runtime_t) -+files_search_all(container_runtime_t) -+files_read_usr_symlinks(container_runtime_t) -+files_search_locks(container_runtime_t) -+files_dontaudit_unmount_all_mountpoints(container_runtime_t) -+ -+fs_read_cgroup_files(container_runtime_t) -+fs_read_tmpfs_symlinks(container_runtime_t) -+fs_search_all(container_runtime_t) -+fs_getattr_all_fs(container_runtime_t) -+fs_rw_onload_sockets(container_runtime_t) -+ -+storage_raw_rw_fixed_disk(container_runtime_t) -+ -+auth_use_nsswitch(container_runtime_t) -+auth_dontaudit_getattr_shadow(container_runtime_t) -+ -+init_read_state(container_runtime_t) -+init_status(container_runtime_t) -+#init_stop(container_runtime_t) -+#init_start(container_runtime_t) -+#init_manage_config_transient_files(container_runtime_t) -+gen_require(` -+ type init_t; -+') -+allow container_runtime_t init_t:service manage_service_perms; -+ -+ -+logging_send_audit_msgs(container_runtime_t) -+logging_send_syslog_msg(container_runtime_t) -+ -+miscfiles_read_localization(container_runtime_t) -+miscfiles_dontaudit_access_check_cert(container_runtime_t) -+miscfiles_dontaudit_setattr_fonts_cache_dirs(container_runtime_t) -+miscfiles_read_fonts(container_runtime_t) -+miscfiles_read_hwdata(container_runtime_t) -+fs_relabel_cgroup_dirs(container_runtime_t) -+# fs_relabel_cgroup_files(container_runtime_t) -+allow container_runtime_t cgroup_t:file relabelfrom; -+ -+mount_domtrans(container_runtime_t) -+ -+seutil_read_default_contexts(container_runtime_t) -+seutil_read_config(container_runtime_t) -+ -+sysnet_dns_name_resolve(container_runtime_t) -+sysnet_exec_ifconfig(container_runtime_t) -+ -+optional_policy(` -+ ssh_use_ptys(container_runtime_t) -+') -+ -+optional_policy(` -+ rpm_exec(container_runtime_t) -+ rpm_read_db(container_runtime_t) -+ rpm_exec(container_runtime_t) -+') -+ -+optional_policy(` -+ fstools_domtrans(container_runtime_t) -+') -+ -+optional_policy(` -+ iptables_domtrans(container_runtime_t) -+') -+ -+optional_policy(` -+ openvswitch_stream_connect(container_runtime_t) -+') -+ -+# -+# lxc rules -+# -+ -+allow container_runtime_t self:capability ~{ sys_module }; -+allow container_runtime_t self:capability2 ~{ mac_override mac_admin }; -+allow container_runtime_t self:cap_userns ~{ sys_module }; -+allow container_runtime_t self:cap2_userns ~{ mac_override mac_admin }; -+ -+allow container_runtime_t self:process { getcap setcap setexec setpgid setsched signal_perms }; -+ -+allow container_runtime_t self:netlink_route_socket rw_netlink_socket_perms;; -+allow container_runtime_t self:netlink_xfrm_socket create_netlink_socket_perms; -+allow container_runtime_t self:netlink_audit_socket create_netlink_socket_perms; -+allow container_runtime_t self:unix_dgram_socket { create_socket_perms sendto }; -+allow container_runtime_t self:unix_stream_socket { create_stream_socket_perms connectto }; -+ -+allow container_runtime_t container_var_lib_t:dir mounton; -+allow container_runtime_t container_var_lib_t:chr_file mounton; -+can_exec(container_runtime_t, container_var_lib_t) -+ -+kernel_dontaudit_setsched(container_runtime_t) -+kernel_get_sysvipc_info(container_runtime_t) -+kernel_request_load_module(container_runtime_t) -+kernel_mounton_messages(container_runtime_t) -+kernel_mounton_all_proc(container_runtime_t) -+kernel_mounton_all_sysctls(container_runtime_t) -+kernel_list_all_proc(container_runtime_t) -+kernel_read_all_sysctls(container_runtime_t) -+kernel_rw_net_sysctls(container_runtime_t) -+kernel_rw_unix_sysctls(container_runtime_t) -+kernel_dontaudit_search_kernel_sysctl(container_runtime_t) -+kernel_dontaudit_access_check_proc(container_runtime_t) -+kernel_dontaudit_setattr_proc_files(container_runtime_t) -+kernel_dontaudit_setattr_proc_dirs(container_runtime_t) -+#kernel_dontaudit_write_usermodehelper_state(container_runtime_t) -+gen_require(` -+ type usermodehelper_t; -+') -+dontaudit container_runtime_t usermodehelper_t:file write; -+ -+dev_getattr_all(container_runtime_t) -+dev_getattr_sysfs_fs(container_runtime_t) -+dev_read_rand(container_runtime_t) -+dev_read_urand(container_runtime_t) -+dev_read_lvm_control(container_runtime_t) -+dev_rw_sysfs(container_runtime_t) -+dev_rw_loop_control(container_runtime_t) -+dev_rw_lvm_control(container_runtime_t) -+dev_read_mtrr(container_runtime_t) -+ -+files_getattr_isid_type_dirs(container_runtime_t) -+files_manage_isid_type_dirs(container_runtime_t) -+files_manage_isid_type_files(container_runtime_t) -+files_manage_isid_type_symlinks(container_runtime_t) -+files_manage_isid_type_chr_files(container_runtime_t) -+files_manage_isid_type_blk_files(container_runtime_t) -+files_exec_isid_files(container_runtime_t) -+files_mounton_isid(container_runtime_t) -+files_mounton_non_security(container_runtime_t) -+files_mounton_isid_type_chr_file(container_runtime_t) -+ -+fs_mount_all_fs(container_runtime_t) -+fs_unmount_all_fs(container_runtime_t) -+fs_remount_all_fs(container_runtime_t) -+files_mounton_isid(container_runtime_t) -+fs_manage_cgroup_dirs(container_runtime_t) -+fs_manage_cgroup_files(container_runtime_t) -+#fs_rw_nsfs_files(container_runtime_t) -+gen_require(` -+ type nsfs_t; -+') -+rw_files_pattern(container_runtime_t, nsfs_t, nsfs_t) -+ -+fs_relabelfrom_xattr_fs(container_runtime_t) -+fs_relabelfrom_tmpfs(container_runtime_t) -+fs_read_tmpfs_symlinks(container_runtime_t) -+fs_list_hugetlbfs(container_runtime_t) -+fs_getattr_all_fs(container_runtime_t) -+fs_list_inotifyfs(container_runtime_t) -+fs_rw_inherited_tmpfs_files(container_runtime_t) -+fs_read_hugetlbfs_files(container_runtime_t) -+fs_read_tmpfs_symlinks(container_runtime_t) -+fs_search_tmpfs(container_runtime_t) -+fs_rw_hugetlbfs_files(container_runtime_t) -+ -+ -+term_use_generic_ptys(container_runtime_t) -+term_use_ptmx(container_runtime_t) -+term_getattr_pty_fs(container_runtime_t) -+term_relabel_pty_fs(container_runtime_t) -+term_mounton_unallocated_ttys(container_runtime_t) -+ -+modutils_domtrans_insmod(container_runtime_t) -+ -+systemd_status_all_unit_files(container_runtime_t) -+systemd_start_systemd_services(container_runtime_t) -+systemd_dbus_chat_logind(container_runtime_t) -+ -+userdom_stream_connect(container_runtime_t) -+userdom_search_user_home_content(container_runtime_t) -+userdom_read_all_users_state(container_runtime_t) -+userdom_relabel_user_home_files(container_runtime_t) -+userdom_relabel_user_tmp_files(container_runtime_t) -+userdom_relabel_user_tmp_dirs(container_runtime_t) -+userdom_use_inherited_user_terminals(container_runtime_t) -+userdom_use_user_ptys(container_runtime_t) -+ -+tunable_policy(`virt_use_nfs',` -+ fs_manage_nfs_dirs(container_runtime_t) -+ fs_manage_nfs_files(container_runtime_t) -+ fs_manage_nfs_named_sockets(container_runtime_t) -+ fs_manage_nfs_symlinks(container_runtime_t) -+ fs_mount_nfs(container_runtime_t) -+ fs_unmount_nfs(container_runtime_t) -+ fs_exec_nfs_files(container_runtime_t) -+ kernel_rw_fs_sysctls(container_runtime_t) -+') -+ -+tunable_policy(`virt_use_samba',` -+ fs_manage_cifs_files(container_runtime_t) -+ fs_manage_cifs_dirs(container_runtime_t) -+ fs_manage_cifs_named_sockets(container_runtime_t) -+ fs_manage_cifs_symlinks(container_runtime_t) -+ fs_exec_cifs_files(container_runtime_t) -+') -+ -+tunable_policy(`virt_sandbox_use_fusefs',` -+ fs_manage_fusefs_dirs(container_runtime_t) -+ fs_manage_fusefs_files(container_runtime_t) -+ fs_manage_fusefs_symlinks(container_runtime_t) -+ fs_mount_fusefs(container_runtime_t) -+ fs_unmount_fusefs(container_runtime_t) -+ fs_exec_fusefs_files(container_runtime_t) -+') -+ -+optional_policy(` -+ virt_stub_svirt_sandbox_domain() -+ container_read_share_files(svirt_sandbox_domain) -+ container_exec_share_files(svirt_sandbox_domain) -+ allow svirt_sandbox_domain container_share_t:file execmod; -+ container_lib_filetrans(svirt_sandbox_domain,container_file_t, sock_file) -+ container_use_ptys(svirt_sandbox_domain) -+ container_spc_stream_connect(svirt_sandbox_domain) -+ fs_dontaudit_remount_tmpfs(svirt_sandbox_domain) -+ dev_dontaudit_mounton_sysfs(svirt_sandbox_domain) -+ allow svirt_sandbox_domain container_file_t:dir_file_class_set { relabelfrom relabelto }; -+') -+ -+optional_policy(` -+ apache_exec_modules(container_runtime_t) -+ apache_read_sys_content(container_runtime_t) -+') -+ -+optional_policy(` -+ gpm_getattr_gpmctl(container_runtime_t) -+') -+ -+optional_policy(` -+ dbus_system_bus_client(container_runtime_t) -+ init_dbus_chat(container_runtime_t) -+ init_start_transient_unit(container_runtime_t) -+ -+ optional_policy(` -+ systemd_dbus_chat_logind(container_runtime_t) -+ systemd_dbus_chat_machined(container_runtime_t) -+ ') -+ -+ optional_policy(` -+ dnsmasq_dbus_chat(container_runtime_t) -+ ') -+ -+ optional_policy(` -+ firewalld_dbus_chat(container_runtime_t) -+ ') -+') -+ -+optional_policy(` -+ lvm_domtrans(container_runtime_t) -+') -+ -+optional_policy(` -+ udev_read_db(container_runtime_t) -+') -+ -+optional_policy(` -+ unconfined_domain(container_runtime_t) -+') -+ -+optional_policy(` -+ virt_read_config(container_runtime_t) -+ virt_exec(container_runtime_t) -+ virt_stream_connect(container_runtime_t) -+ virt_stream_connect_sandbox(container_runtime_t) -+ virt_exec_sandbox_files(container_runtime_t) -+ virt_manage_sandbox_files(container_runtime_t) -+ virt_relabel_sandbox_filesystem(container_runtime_t) -+ # for lxc -+ virt_transition_svirt_sandbox(container_runtime_t, system_r) -+ virt_transition_svirt(container_runtime_t, system_r) -+ allow svirt_sandbox_domain container_runtime_t:fd use; -+ virt_mounton_sandbox_file(container_runtime_t) -+# virt_attach_sandbox_tun_iface(container_runtime_t) -+ allow container_runtime_t svirt_sandbox_domain:tun_socket relabelfrom; -+ virt_sandbox_entrypoint(container_runtime_t) -+ virt_stub_lxc() -+ allow container_runtime_t virtd_lxc_t:unix_stream_socket { rw_stream_socket_perms connectto }; -+ -+') -+ -+tunable_policy(`container_connect_any',` -+ corenet_tcp_connect_all_ports(container_runtime_t) -+ corenet_sendrecv_all_packets(container_runtime_t) -+ corenet_tcp_sendrecv_all_ports(container_runtime_t) -+') -+ -+######################################## -+# -+# spc local policy -+# -+allow spc_t { container_var_lib_t container_share_t }:file entrypoint; -+role system_r types spc_t; -+ -+domtrans_pattern(container_runtime_t, container_share_t, spc_t) -+domtrans_pattern(container_runtime_t, container_var_lib_t, spc_t) -+allow container_runtime_t spc_t:process2 nnp_transition; -+allow spc_t container_runtime_t:fifo_file manage_fifo_file_perms; -+allow spc_t { container_share_t container_file_t }:system module_load; -+ -+allow container_runtime_t spc_t:process { setsched signal_perms }; -+ps_process_pattern(container_runtime_t, spc_t) -+allow container_runtime_t spc_t:socket_class_set { relabelto relabelfrom }; -+ -+init_dbus_chat(spc_t) -+ -+optional_policy(` -+ systemd_dbus_chat_machined(spc_t) -+ systemd_dbus_chat_logind(spc_t) -+') -+ -+optional_policy(` -+ dbus_chat_system_bus(spc_t) -+ dbus_chat_session_bus(spc_t) -+ dnsmasq_dbus_chat(spc_t) -+') -+ -+optional_policy(` -+ unconfined_domain_noaudit(spc_t) -+ domain_ptrace_all_domains(spc_t) -+') -+ -+optional_policy(` -+ virt_stub_svirt_sandbox_file() -+ virt_transition_svirt_sandbox(spc_t, system_r) -+ virt_sandbox_entrypoint(spc_t) -+# virt_sandbox_domtrans(container_runtime_t, spc_t) -+ domtrans_pattern(container_runtime_t, container_file_t, spc_t) -+ virt_transition_svirt(spc_t, system_r) -+ virt_sandbox_entrypoint(container_file_t) -+ virt_sandbox_entrypoint(container_share_t) -+ -+ gen_require(` -+ attribute virt_domain; -+ ') -+ container_spc_read_state(virt_domain) -+ container_spc_rw_pipes(virt_domain) -+') -+ -+######################################## -+# -+# container_auth local policy -+# -+allow container_auth_t self:fifo_file rw_fifo_file_perms; -+allow container_auth_t self:unix_stream_socket create_stream_socket_perms; -+dontaudit container_auth_t self:capability net_admin; -+ -+container_stream_connect(container_auth_t) -+ -+manage_dirs_pattern(container_auth_t, container_plugin_var_run_t, container_plugin_var_run_t) -+manage_files_pattern(container_auth_t, container_plugin_var_run_t, container_plugin_var_run_t) -+manage_sock_files_pattern(container_auth_t, container_plugin_var_run_t, container_plugin_var_run_t) -+manage_lnk_files_pattern(container_auth_t, container_plugin_var_run_t, container_plugin_var_run_t) -+files_pid_filetrans(container_auth_t, container_plugin_var_run_t, { dir file lnk_file sock_file }) -+ -+stream_connect_pattern(container_runtime_t, container_plugin_var_run_t, container_plugin_var_run_t, container_auth_t) -+list_dirs_pattern(container_runtime_t, container_plugin_var_run_t, container_plugin_var_run_t) -+ -+domain_use_interactive_fds(container_auth_t) -+ -+kernel_read_net_sysctls(container_auth_t) -+ -+auth_use_nsswitch(container_auth_t) -+ -+files_read_etc_files(container_auth_t) -+ -+miscfiles_read_localization(container_auth_t) -+ -+sysnet_dns_name_resolve(container_auth_t) -+ -+######################################## -+# -+# container_t local policy -+# -+# Currently this is called in virt.te -+# virt_sandbox_domain_template(container) -+# typealias container_t alias svirt_lxc_net_t; -+gen_require(` -+ type container_t; -+') -+typeattribute container_t container_domain, container_net_domain; -+allow container_runtime_t container_domain:fifo_file rw_fifo_file_perms; -+allow container_domain container_runtime_t:fifo_file { rw_fifo_file_perms }; -+allow container_domain container_runtime_t:fd use; -+allow container_runtime_t container_domain:fd use; -+allow container_domain self:socket_class_set create_socket_perms; -+ -+dontaudit container_domain self:capability fsetid; -+allow container_domain self:association sendto; -+allow container_domain self:dir list_dir_perms; -+dontaudit container_domain self:dir write; -+allow container_domain self:file rw_file_perms; -+allow container_domain self:lnk_file read_file_perms; -+allow container_domain self:fifo_file create_fifo_file_perms; -+allow container_domain self:filesystem associate; -+allow container_domain self:key manage_key_perms; -+allow container_domain self:netlink_route_socket r_netlink_socket_perms; -+allow container_domain self:netlink_kobject_uevent_socket create_socket_perms; -+allow container_domain self:netlink_xfrm_socket create_socket_perms; -+allow container_domain self:packet_socket create_socket_perms; -+allow container_domain self:passwd rootok; -+allow container_domain self:peer recv; -+allow container_domain self:process { execmem execstack fork getattr getcap getpgid getsched getsession setcap setpgid setrlimit setsched sigchld sigkill signal signull sigstop }; -+allow container_domain self:sem create_sem_perms; -+allow container_domain self:shm create_shm_perms; -+allow container_domain self:socket create_socket_perms; -+allow container_domain self:tcp_socket create_socket_perms; -+allow container_domain self:tun_socket create_socket_perms; -+allow container_domain self:udp_socket create_socket_perms; -+allow container_domain self:unix_dgram_socket create_socket_perms; -+allow container_domain self:unix_stream_socket create_stream_socket_perms; -+dontaudit container_domain self:capability2 block_suspend ; -+allow container_domain self:unix_stream_socket { sendto create_stream_socket_perms }; -+ -+manage_files_pattern(container_domain, container_file_t, container_file_t) -+exec_files_pattern(container_domain, container_file_t, container_file_t) -+manage_lnk_files_pattern(container_domain, container_file_t, container_file_t) -+manage_dirs_pattern(container_domain, container_file_t, container_file_t) -+manage_chr_files_pattern(container_domain, container_file_t, container_file_t) -+allow container_domain container_file_t:chr_file mmap_file_perms; -+manage_blk_files_pattern(container_domain, container_file_t, container_file_t) -+allow container_domain container_file_t:filesystem { mount remount unmount }; -+fs_tmpfs_filetrans(container_domain, container_file_t, { dir file }) -+allow container_domain container_file_t:dir_file_class_set { relabelfrom relabelto }; -+container_read_share_files(container_domain) -+container_exec_share_files(container_domain) -+container_use_ptys(container_domain) -+container_spc_stream_connect(container_domain) -+container_stream_connect(container_domain) -+fs_dontaudit_remount_tmpfs(container_domain) -+ -+dev_dontaudit_mounton_sysfs(container_domain) -+allow container_domain container_file_t:dir_file_class_set { relabelfrom relabelto }; -+dev_dontaudit_mounton_sysfs(container_domain) -+ -+dontaudit container_domain container_runtime_tmpfs_t:dir read; -+dev_getattr_mtrr_dev(container_domain) -+dev_list_sysfs(container_domain) -+ -+allow svirt_sandbox_domain self:key manage_key_perms; -+dontaudit svirt_sandbox_domain svirt_sandbox_domain:key search; -+ -+allow container_domain self:process { getattr signal_perms getsched getpgid getcap setsched setcap setpgid setrlimit }; -+allow container_domain self:fifo_file manage_file_perms; -+allow container_domain self:msg all_msg_perms; -+allow container_domain self:sem create_sem_perms; -+allow container_domain self:shm create_shm_perms; -+allow container_domain self:msgq create_msgq_perms; -+allow container_domain self:unix_stream_socket { create_stream_socket_perms connectto }; -+allow container_domain self:unix_dgram_socket { sendto create_socket_perms }; -+allow container_domain self:passwd rootok; -+allow container_domain self:filesystem associate; -+allow container_domain self:netlink_kobject_uevent_socket create_socket_perms; -+ -+kernel_getattr_proc(container_domain) -+kernel_list_all_proc(container_domain) -+kernel_read_all_sysctls(container_domain) -+kernel_read_network_state(container_domain) -+kernel_rw_net_sysctls(container_domain) -+kernel_rw_unix_sysctls(container_domain) -+kernel_dontaudit_search_kernel_sysctl(container_domain) -+kernel_dontaudit_access_check_proc(container_domain) -+kernel_dontaudit_setattr_proc_files(container_domain) -+kernel_dontaudit_setattr_proc_dirs(container_domain) -+#kernel_dontaudit_write_usermodehelper_state(container_domain) -+dontaudit container_domain usermodehelper_t:file write; -+ -+kernel_read_irq_sysctls(container_domain) -+kernel_get_sysvipc_info(container_domain) -+ -+fs_getattr_all_fs(container_domain) -+fs_list_inotifyfs(container_domain) -+fs_rw_inherited_tmpfs_files(container_domain) -+fs_read_hugetlbfs_files(container_domain) -+fs_read_tmpfs_symlinks(container_domain) -+fs_search_tmpfs(container_domain) -+fs_rw_hugetlbfs_files(container_domain) -+fs_dontaudit_getattr_all_dirs(container_domain) -+fs_dontaudit_getattr_all_files(container_domain) -+ -+term_use_all_inherited_terms(container_domain) -+ -+userdom_use_user_ptys(container_domain) -+ -+#domain_dontaudit_link_all_domains_keyrings(container_domain) -+#domain_dontaudit_search_all_domains_keyrings(container_domain) -+ -+virt_stub_svirt_sandbox_file() -+#virt_sandbox_net_domain(container_t) -+gen_require(` -+ attribute sandbox_net_domain; -+') -+virt_sandbox_domain(container_t) -+typeattribute container_t sandbox_net_domain; -+ -+logging_send_syslog_msg(container_t) -+ -+fs_noxattr_type(container_file_t) -+# fs_associate_cgroupfs(container_file_t) -+gen_require(` -+ type cgroup_t; -+') -+ -+dev_read_sysfs(container_domain) -+dev_read_mtrr(container_domain) -+dev_read_rand(container_t) -+dev_read_urand(container_t) -+ -+files_read_kernel_modules(container_t) -+ -+allow container_file_t cgroup_t:filesystem associate; -+term_pty(container_file_t) -+tunable_policy(`virt_sandbox_use_sys_admin',` -+ allow container_t self:capability sys_admin; -+ allow container_t self:cap_userns sys_admin; -+') -+ -+allow container_domain self:cap_userns sys_admin; -+allow container_domain self:process { getsession execstack execmem }; -+ -+virt_default_capabilities(container_t) -+kernel_rw_rpc_sysctls(container_domain) -+kernel_rw_net_sysctls(container_domain) -+kernel_read_messages(container_t) -+kernel_read_network_state(container_domain) -+kernel_dontaudit_write_proc_files(container_domain) -+ -+# Container Net Domain -+corenet_tcp_bind_generic_node(container_net_domain) -+corenet_udp_bind_generic_node(container_net_domain) -+corenet_raw_bind_generic_node(container_net_domain) -+corenet_tcp_sendrecv_all_ports(container_net_domain) -+corenet_udp_sendrecv_all_ports(container_net_domain) -+corenet_udp_bind_all_ports(container_net_domain) -+corenet_tcp_bind_all_ports(container_net_domain) -+corenet_tcp_connect_all_ports(container_net_domain) -+ -+allow container_net_domain self:udp_socket create_socket_perms; -+allow container_net_domain self:tcp_socket create_stream_socket_perms; -+allow container_net_domain self:tun_socket create_socket_perms; -+allow container_net_domain self:netlink_route_socket create_netlink_socket_perms; -+allow container_net_domain self:packet_socket create_socket_perms; -+allow container_net_domain self:socket create_socket_perms; -+allow container_net_domain self:rawip_socket create_stream_socket_perms; -+allow container_net_domain self:netlink_kobject_uevent_socket create_socket_perms; -+allow container_net_domain self:netlink_xfrm_socket create_netlink_socket_perms; -+ -+kernel_unlabeled_domtrans(container_runtime_t, spc_t) -+kernel_unlabeled_entry_type(spc_t) -+#kernel_dontaudit_write_usermodehelper_state(container_t) -+gen_require(` -+ type usermodehelper_t; -+') -+dontaudit container_t usermodehelper_t:file write; -+ -+fs_read_cgroup_files(container_t) -+fs_list_cgroup_dirs(container_t) -+ -+sysnet_read_config(container_t) -+ -+corenet_tcp_bind_generic_node(container_t) -+corenet_udp_bind_generic_node(container_t) -+corenet_raw_bind_generic_node(container_t) -+corenet_tcp_sendrecv_all_ports(container_t) -+corenet_udp_sendrecv_all_ports(container_t) -+corenet_udp_bind_all_ports(container_t) -+corenet_tcp_bind_all_ports(container_t) -+corenet_tcp_connect_all_ports(container_t) -+ -+allow container_t self:udp_socket create_socket_perms; -+allow container_t self:tcp_socket create_stream_socket_perms; -+allow container_t self:tun_socket create_socket_perms; -+allow container_t self:netlink_route_socket create_netlink_socket_perms; -+allow container_t self:packet_socket create_socket_perms; -+allow container_t self:socket create_socket_perms; -+allow container_t self:rawip_socket create_stream_socket_perms; -+allow container_t self:netlink_kobject_uevent_socket create_socket_perms; -+allow container_t self:netlink_xfrm_socket create_netlink_socket_perms; -+allow container_t self:cap_userns { chown dac_override fowner kill setgid setuid setpcap net_bind_service net_raw sys_chroot mknod audit_write setfcap }; -+ -+optional_policy(` -+ sssd_stream_connect(container_t) -+') -+ -+optional_policy(` -+ systemd_dbus_chat_logind(container_t) -+') -+ -+tunable_policy(`container_manage_cgroup',` -+ fs_manage_cgroup_dirs(container_t) -+ fs_manage_cgroup_files(container_t) -+') -+ -+tunable_policy(`virt_sandbox_use_fusefs',` -+ fs_manage_fusefs_dirs(container_t) -+ fs_manage_fusefs_files(container_t) -+ fs_manage_fusefs_symlinks(container_t) -+ fs_mount_fusefs(container_t) -+ fs_unmount_fusefs(container_t) -+ fs_exec_fusefs_files(container_t) -+') -+ -+tunable_policy(`virt_sandbox_use_netlink',` -+ allow container_t self:netlink_socket create_socket_perms; -+ allow container_t self:netlink_tcpdiag_socket create_netlink_socket_perms; -+ allow container_t self:netlink_kobject_uevent_socket create_socket_perms; -+', ` -+ logging_dontaudit_send_audit_msgs(container_t) -+') -+ -+tunable_policy(`virt_sandbox_use_audit',` -+ logging_send_audit_msgs(container_t) -+') -+ -+tunable_policy(`virt_sandbox_use_all_caps',` -+ allow container_t self:capability ~{ sys_module }; -+ allow container_t self:capability2 ~{ mac_override mac_admin }; -+ allow container_t self:cap_userns ~{ sys_module }; -+ allow container_t self:cap2_userns ~{ mac_override mac_admin }; -+') -+ -+tunable_policy(`virt_sandbox_use_mknod',` -+ allow container_t self:capability mknod; -+ allow container_t self:cap_userns mknod; -+') -+ -+gen_require(` -+ type iptables_t; -+') -+container_read_pid_files(iptables_t) -+container_read_state(iptables_t) -+ -+optional_policy(` -+ gen_require(` -+ type unconfined_service_t; -+ ') -+ -+ virt_transition_svirt_sandbox(unconfined_service_t, system_r) -+ container_filetrans_named_content(unconfined_service_t) -+ container_runtime_domtrans(unconfined_service_t) -+') -+ -+optional_policy(` -+ gen_require(` -+ attribute unconfined_domain_type; -+ ') -+ -+ container_filetrans_named_content(unconfined_domain_type) -+ allow unconfined_domain_type container_domain:process2 { nnp_transition nosuid_transition }; -+') -+ -+# Container build -+container_domain_template(container_build) -+dev_mount_sysfs_fs(container_build_t) -+dev_mounton_sysfs(container_build_t) -+ -+fs_mount_tmpfs(container_build_t) -+fs_remount_cgroup(container_build_t) -+ -+kernel_mount_proc(container_build_t) -+kernel_mount_proc(container_build_t) -+kernel_mounton_proc(container_build_t) -+kernel_mounton_proc(container_build_t) -+ -+term_use_generic_ptys(container_build_t) -+term_setattr_generic_ptys(container_build_t) -+term_mount_pty_fs(container_build_t) -+ -+allow container_build_t self:capability ~{ sys_module }; -+allow container_build_t self:capability2 ~{ mac_override mac_admin }; -+allow container_build_t self:cap_userns ~{ sys_module }; -+allow container_build_t self:cap2_userns ~{ mac_override mac_admin }; -+allow container_build_t self:capability mknod; -+allow container_build_t self:cap_userns mknod; -+ -+optional_policy(` -+ gen_require(` -+ type proc_t, proc_kcore_t; -+ type sysctl_t, sysctl_irq_t; -+ ') -+ -+ allow container_build_t proc_t:filesystem { remount }; -+ allow container_build_t proc_kcore_t:file mounton; -+ allow container_build_t sysctl_irq_t:dir mounton; -+ allow container_build_t sysctl_t:dir mounton; -+ allow container_build_t sysctl_t:file mounton; -+') -+ -+# Container Logreader -+container_domain_template(container_logreader) -+typeattribute container_logreader_t container_net_domain; -+logging_read_all_logs(container_logreader_t) -+logging_read_audit_log(container_logreader_t) -+logging_list_logs(container_logreader_t) -+ -+tunable_policy(`virt_sandbox_use_all_caps',` -+ allow container_logreader_t self:capability ~{ sys_module }; -+ allow container_logreader_t self:capability2 ~{ mac_override mac_admin }; -+ allow container_logreader_t self:cap_userns ~{ sys_module }; -+ allow container_logreader_t self:cap2_userns ~{ mac_override mac_admin }; -+') -diff --git a/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.fc b/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.fc -deleted file mode 100644 -index e9bb863da0..0000000000 ---- a/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.fc -+++ /dev/null -@@ -1,20 +0,0 @@ --/root/\.docker gen_context(system_u:object_r:docker_home_t,s0) -- --/usr/bin/docker -- gen_context(system_u:object_r:docker_exec_t,s0) --/usr/bin/dockerd -- gen_context(system_u:object_r:docker_exec_t,s0) --/usr/lib/systemd/system/docker.service -- gen_context(system_u:object_r:docker_unit_file_t,s0) -- --/etc/docker(/.*)? gen_context(system_u:object_r:docker_config_t,s0) -- --/var/lib/docker(/.*)? gen_context(system_u:object_r:docker_var_lib_t,s0) --/var/lib/kublet(/.*)? gen_context(system_u:object_r:docker_var_lib_t,s0) --/var/lib/docker/vfs(/.*)? gen_context(system_u:object_r:svirt_sandbox_file_t,s0) -- --/var/run/docker\.pid -- gen_context(system_u:object_r:docker_var_run_t,s0) --/var/run/docker\.sock -s gen_context(system_u:object_r:docker_var_run_t,s0) --/var/run/docker-client(/.*)? gen_context(system_u:object_r:docker_var_run_t,s0) -- --/var/lib/docker/init(/.*)? gen_context(system_u:object_r:docker_share_t,s0) --/var/lib/docker/containers/.*/hosts gen_context(system_u:object_r:docker_share_t,s0) --/var/lib/docker/containers/.*/hostname gen_context(system_u:object_r:docker_share_t,s0) --/var/lib/docker/.*/config\.env gen_context(system_u:object_r:docker_share_t,s0) -diff --git a/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.if b/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.if -deleted file mode 100644 -index ca075c05c5..0000000000 ---- a/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.if -+++ /dev/null -@@ -1,461 +0,0 @@ -- --## The open-source application container engine. -- --######################################## --## --## Execute docker in the docker domain. --## --## --## --## Domain allowed to transition. --## --## --# --interface(`docker_domtrans',` -- gen_require(` -- type docker_t, docker_exec_t; -- ') -- -- corecmd_search_bin($1) -- domtrans_pattern($1, docker_exec_t, docker_t) --') -- --######################################## --## --## Execute docker in the caller domain. --## --## --## --## Domain allowed to transition. --## --## --# --interface(`docker_exec',` -- gen_require(` -- type docker_exec_t; -- ') -- -- corecmd_search_bin($1) -- can_exec($1, docker_exec_t) --') -- --######################################## --## --## Search docker lib directories. --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_search_lib',` -- gen_require(` -- type docker_var_lib_t; -- ') -- -- allow $1 docker_var_lib_t:dir search_dir_perms; -- files_search_var_lib($1) --') -- --######################################## --## --## Execute docker lib directories. --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_exec_lib',` -- gen_require(` -- type docker_var_lib_t; -- ') -- -- allow $1 docker_var_lib_t:dir search_dir_perms; -- can_exec($1, docker_var_lib_t) --') -- --######################################## --## --## Read docker lib files. --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_read_lib_files',` -- gen_require(` -- type docker_var_lib_t; -- ') -- -- files_search_var_lib($1) -- read_files_pattern($1, docker_var_lib_t, docker_var_lib_t) --') -- --######################################## --## --## Read docker share files. --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_read_share_files',` -- gen_require(` -- type docker_share_t; -- ') -- -- files_search_var_lib($1) -- read_files_pattern($1, docker_share_t, docker_share_t) --') -- --######################################## --## --## Manage docker lib files. --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_manage_lib_files',` -- gen_require(` -- type docker_var_lib_t; -- ') -- -- files_search_var_lib($1) -- manage_files_pattern($1, docker_var_lib_t, docker_var_lib_t) -- manage_lnk_files_pattern($1, docker_var_lib_t, docker_var_lib_t) --') -- --######################################## --## --## Manage docker lib directories. --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_manage_lib_dirs',` -- gen_require(` -- type docker_var_lib_t; -- ') -- -- files_search_var_lib($1) -- manage_dirs_pattern($1, docker_var_lib_t, docker_var_lib_t) --') -- --######################################## --## --## Create objects in a docker var lib directory --## with an automatic type transition to --## a specified private type. --## --## --## --## Domain allowed access. --## --## --## --## --## The type of the object to create. --## --## --## --## --## The class of the object to be created. --## --## --## --## --## The name of the object being created. --## --## --# --interface(`docker_lib_filetrans',` -- gen_require(` -- type docker_var_lib_t; -- ') -- -- filetrans_pattern($1, docker_var_lib_t, $2, $3, $4) --') -- --######################################## --## --## Read docker PID files. --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_read_pid_files',` -- gen_require(` -- type docker_var_run_t; -- ') -- -- files_search_pids($1) -- read_files_pattern($1, docker_var_run_t, docker_var_run_t) --') -- --######################################## --## --## Execute docker server in the docker domain. --## --## --## --## Domain allowed to transition. --## --## --# --interface(`docker_systemctl',` -- gen_require(` -- type docker_t; -- type docker_unit_file_t; -- ') -- -- systemd_exec_systemctl($1) -- init_reload_services($1) -- systemd_read_fifo_file_passwd_run($1) -- allow $1 docker_unit_file_t:file read_file_perms; -- allow $1 docker_unit_file_t:service manage_service_perms; -- -- ps_process_pattern($1, docker_t) --') -- --######################################## --## --## Read and write docker shared memory. --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_rw_sem',` -- gen_require(` -- type docker_t; -- ') -- -- allow $1 docker_t:sem rw_sem_perms; --') -- --####################################### --## --## Read and write the docker pty type. --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_use_ptys',` -- gen_require(` -- type docker_devpts_t; -- ') -- -- allow $1 docker_devpts_t:chr_file rw_term_perms; --') -- --####################################### --## --## Allow domain to create docker content --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_filetrans_named_content',` -- -- gen_require(` -- type docker_var_lib_t; -- type docker_share_t; -- type docker_log_t; -- type docker_var_run_t; -- type docker_home_t; -- ') -- -- files_pid_filetrans($1, docker_var_run_t, file, "docker.pid") -- files_pid_filetrans($1, docker_var_run_t, sock_file, "docker.sock") -- files_pid_filetrans($1, docker_var_run_t, dir, "docker-client") -- files_var_lib_filetrans($1, docker_var_lib_t, dir, "docker") -- filetrans_pattern($1, docker_var_lib_t, docker_share_t, file, "config.env") -- filetrans_pattern($1, docker_var_lib_t, docker_share_t, file, "hosts") -- filetrans_pattern($1, docker_var_lib_t, docker_share_t, file, "hostname") -- filetrans_pattern($1, docker_var_lib_t, docker_share_t, file, "resolv.conf") -- filetrans_pattern($1, docker_var_lib_t, docker_share_t, dir, "init") -- userdom_admin_home_dir_filetrans($1, docker_home_t, dir, ".docker") --') -- --######################################## --## --## Connect to docker over a unix stream socket. --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_stream_connect',` -- gen_require(` -- type docker_t, docker_var_run_t; -- ') -- -- files_search_pids($1) -- stream_connect_pattern($1, docker_var_run_t, docker_var_run_t, docker_t) --') -- --######################################## --## --## Connect to SPC containers over a unix stream socket. --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_spc_stream_connect',` -- gen_require(` -- type spc_t, spc_var_run_t; -- ') -- -- files_search_pids($1) -- files_write_all_pid_sockets($1) -- allow $1 spc_t:unix_stream_socket connectto; --') -- -- --######################################## --## --## All of the rules required to administrate --## an docker environment --## --## --## --## Domain allowed access. --## --## --# --interface(`docker_admin',` -- gen_require(` -- type docker_t; -- type docker_var_lib_t, docker_var_run_t; -- type docker_unit_file_t; -- type docker_lock_t; -- type docker_log_t; -- type docker_config_t; -- ') -- -- allow $1 docker_t:process { ptrace signal_perms }; -- ps_process_pattern($1, docker_t) -- -- admin_pattern($1, docker_config_t) -- -- files_search_var_lib($1) -- admin_pattern($1, docker_var_lib_t) -- -- files_search_pids($1) -- admin_pattern($1, docker_var_run_t) -- -- files_search_locks($1) -- admin_pattern($1, docker_lock_t) -- -- logging_search_logs($1) -- admin_pattern($1, docker_log_t) -- -- docker_systemctl($1) -- admin_pattern($1, docker_unit_file_t) -- allow $1 docker_unit_file_t:service all_service_perms; -- -- optional_policy(` -- systemd_passwd_agent_exec($1) -- systemd_read_fifo_file_passwd_run($1) -- ') --') -- --interface(`domain_stub_named_filetrans_domain',` -- gen_require(` -- attribute named_filetrans_domain; -- ') --') -- --interface(`lvm_stub',` -- gen_require(` -- type lvm_t; -- ') --') --interface(`staff_stub',` -- gen_require(` -- type staff_t; -- ') --') --interface(`virt_stub_svirt_sandbox_domain',` -- gen_require(` -- attribute svirt_sandbox_domain; -- ') --') --interface(`virt_stub_svirt_sandbox_file',` -- gen_require(` -- type svirt_sandbox_file_t; -- ') --') --interface(`fs_dontaudit_remount_tmpfs',` -- gen_require(` -- type tmpfs_t; -- ') -- -- dontaudit $1 tmpfs_t:filesystem remount; --') --interface(`dev_dontaudit_list_all_dev_nodes',` -- gen_require(` -- type device_t; -- ') -- -- dontaudit $1 device_t:dir list_dir_perms; --') --interface(`kernel_unlabeled_entry_type',` -- gen_require(` -- type unlabeled_t; -- ') -- -- domain_entry_file($1, unlabeled_t) --') --interface(`kernel_unlabeled_domtrans',` -- gen_require(` -- type unlabeled_t; -- ') -- -- read_lnk_files_pattern($1, unlabeled_t, unlabeled_t) -- domain_transition_pattern($1, unlabeled_t, $2) -- type_transition $1 unlabeled_t:process $2; --') --interface(`files_write_all_pid_sockets',` -- gen_require(` -- attribute pidfile; -- ') -- -- allow $1 pidfile:sock_file write_sock_file_perms; --') --interface(`dev_dontaudit_mounton_sysfs',` -- gen_require(` -- type sysfs_t; -- ') -- -- dontaudit $1 sysfs_t:dir mounton; --') -diff --git a/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.te b/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.te -deleted file mode 100644 -index 999742f302..0000000000 ---- a/components/engine/contrib/selinux-euleros/docker-engine-selinux/docker.te -+++ /dev/null -@@ -1,414 +0,0 @@ --policy_module(docker, 1.0.0) -- --######################################## --# --# Declarations --# -- --## --##

--## Allow sandbox containers manage fuse files --##

--##
--gen_tunable(virt_sandbox_use_fusefs, false) -- --## --##

--## Determine whether docker can --## connect to all TCP ports. --##

--##
--gen_tunable(docker_connect_any, false) -- --type docker_t; --type docker_exec_t; --init_daemon_domain(docker_t, docker_exec_t) --domain_subj_id_change_exemption(docker_t) --domain_role_change_exemption(docker_t) -- --type spc_t; --domain_type(spc_t) --role system_r types spc_t; -- --type spc_var_run_t; --files_pid_file(spc_var_run_t) -- --type docker_var_lib_t; --files_type(docker_var_lib_t) -- --type docker_home_t; --userdom_user_home_content(docker_home_t) -- --type docker_config_t; --files_config_file(docker_config_t) -- --type docker_lock_t; --files_lock_file(docker_lock_t) -- --type docker_log_t; --logging_log_file(docker_log_t) -- --type docker_tmp_t; --files_tmp_file(docker_tmp_t) -- --type docker_tmpfs_t; --files_tmpfs_file(docker_tmpfs_t) -- --type docker_var_run_t; --files_pid_file(docker_var_run_t) -- --type docker_unit_file_t; --systemd_unit_file(docker_unit_file_t) -- --type docker_devpts_t; --term_pty(docker_devpts_t) -- --type docker_share_t; --files_type(docker_share_t) -- --######################################## --# --# docker local policy --# --allow docker_t self:capability { chown kill fowner fsetid mknod net_admin net_bind_service net_raw setfcap }; --allow docker_t self:tun_socket relabelto; --allow docker_t self:process { getattr signal_perms setrlimit setfscreate }; --allow docker_t self:fifo_file rw_fifo_file_perms; --allow docker_t self:unix_stream_socket create_stream_socket_perms; --allow docker_t self:tcp_socket create_stream_socket_perms; --allow docker_t self:udp_socket create_socket_perms; --allow docker_t self:capability2 block_suspend; -- --manage_files_pattern(docker_t, docker_home_t, docker_home_t) --manage_dirs_pattern(docker_t, docker_home_t, docker_home_t) --manage_lnk_files_pattern(docker_t, docker_home_t, docker_home_t) --userdom_admin_home_dir_filetrans(docker_t, docker_home_t, dir, ".docker") -- --manage_dirs_pattern(docker_t, docker_config_t, docker_config_t) --manage_files_pattern(docker_t, docker_config_t, docker_config_t) --files_etc_filetrans(docker_t, docker_config_t, dir, "docker") -- --manage_dirs_pattern(docker_t, docker_lock_t, docker_lock_t) --manage_files_pattern(docker_t, docker_lock_t, docker_lock_t) -- --manage_dirs_pattern(docker_t, docker_log_t, docker_log_t) --manage_files_pattern(docker_t, docker_log_t, docker_log_t) --manage_lnk_files_pattern(docker_t, docker_log_t, docker_log_t) --logging_log_filetrans(docker_t, docker_log_t, { dir file lnk_file }) --allow docker_t docker_log_t:dir_file_class_set { relabelfrom relabelto }; -- --manage_dirs_pattern(docker_t, docker_tmp_t, docker_tmp_t) --manage_files_pattern(docker_t, docker_tmp_t, docker_tmp_t) --manage_lnk_files_pattern(docker_t, docker_tmp_t, docker_tmp_t) --files_tmp_filetrans(docker_t, docker_tmp_t, { dir file lnk_file }) -- --manage_dirs_pattern(docker_t, docker_tmpfs_t, docker_tmpfs_t) --manage_files_pattern(docker_t, docker_tmpfs_t, docker_tmpfs_t) --manage_lnk_files_pattern(docker_t, docker_tmpfs_t, docker_tmpfs_t) --manage_fifo_files_pattern(docker_t, docker_tmpfs_t, docker_tmpfs_t) --manage_chr_files_pattern(docker_t, docker_tmpfs_t, docker_tmpfs_t) --manage_blk_files_pattern(docker_t, docker_tmpfs_t, docker_tmpfs_t) --allow docker_t docker_tmpfs_t:dir relabelfrom; --can_exec(docker_t, docker_tmpfs_t) --fs_tmpfs_filetrans(docker_t, docker_tmpfs_t, { dir file }) --allow docker_t docker_tmpfs_t:chr_file mounton; -- --manage_dirs_pattern(docker_t, docker_share_t, docker_share_t) --manage_files_pattern(docker_t, docker_share_t, docker_share_t) --manage_lnk_files_pattern(docker_t, docker_share_t, docker_share_t) --allow docker_t docker_share_t:dir_file_class_set { relabelfrom relabelto }; -- --can_exec(docker_t, docker_share_t) --#docker_filetrans_named_content(docker_t) -- --manage_dirs_pattern(docker_t, docker_var_lib_t, docker_var_lib_t) --manage_chr_files_pattern(docker_t, docker_var_lib_t, docker_var_lib_t) --manage_blk_files_pattern(docker_t, docker_var_lib_t, docker_var_lib_t) --manage_files_pattern(docker_t, docker_var_lib_t, docker_var_lib_t) --manage_lnk_files_pattern(docker_t, docker_var_lib_t, docker_var_lib_t) --allow docker_t docker_var_lib_t:dir_file_class_set { relabelfrom relabelto }; --files_var_lib_filetrans(docker_t, docker_var_lib_t, { dir file lnk_file }) -- --manage_dirs_pattern(docker_t, docker_var_run_t, docker_var_run_t) --manage_files_pattern(docker_t, docker_var_run_t, docker_var_run_t) --manage_sock_files_pattern(docker_t, docker_var_run_t, docker_var_run_t) --manage_lnk_files_pattern(docker_t, docker_var_run_t, docker_var_run_t) --files_pid_filetrans(docker_t, docker_var_run_t, { dir file lnk_file sock_file }) -- --allow docker_t docker_devpts_t:chr_file { relabelfrom rw_chr_file_perms setattr_chr_file_perms }; --term_create_pty(docker_t, docker_devpts_t) -- --kernel_read_system_state(docker_t) --kernel_read_network_state(docker_t) --kernel_read_all_sysctls(docker_t) --kernel_rw_net_sysctls(docker_t) --kernel_setsched(docker_t) --kernel_read_all_proc(docker_t) -- --domain_use_interactive_fds(docker_t) --domain_dontaudit_read_all_domains_state(docker_t) -- --corecmd_exec_bin(docker_t) --corecmd_exec_shell(docker_t) -- --corenet_tcp_bind_generic_node(docker_t) --corenet_tcp_sendrecv_generic_if(docker_t) --corenet_tcp_sendrecv_generic_node(docker_t) --corenet_tcp_sendrecv_generic_port(docker_t) --corenet_tcp_bind_all_ports(docker_t) --corenet_tcp_connect_http_port(docker_t) --corenet_tcp_connect_commplex_main_port(docker_t) --corenet_udp_sendrecv_generic_if(docker_t) --corenet_udp_sendrecv_generic_node(docker_t) --corenet_udp_sendrecv_all_ports(docker_t) --corenet_udp_bind_generic_node(docker_t) --corenet_udp_bind_all_ports(docker_t) -- --files_read_config_files(docker_t) --files_dontaudit_getattr_all_dirs(docker_t) --files_dontaudit_getattr_all_files(docker_t) -- --fs_read_cgroup_files(docker_t) --fs_read_tmpfs_symlinks(docker_t) --fs_search_all(docker_t) --fs_getattr_all_fs(docker_t) -- --storage_raw_rw_fixed_disk(docker_t) -- --auth_use_nsswitch(docker_t) --auth_dontaudit_getattr_shadow(docker_t) -- --init_read_state(docker_t) --init_status(docker_t) -- --logging_send_audit_msgs(docker_t) --logging_send_syslog_msg(docker_t) -- --miscfiles_read_localization(docker_t) -- --mount_domtrans(docker_t) -- --seutil_read_default_contexts(docker_t) --seutil_read_config(docker_t) -- --sysnet_dns_name_resolve(docker_t) --sysnet_exec_ifconfig(docker_t) -- --optional_policy(` -- rpm_exec(docker_t) -- rpm_read_db(docker_t) -- rpm_exec(docker_t) --') -- --optional_policy(` -- fstools_domtrans(docker_t) --') -- --optional_policy(` -- iptables_domtrans(docker_t) --') -- --optional_policy(` -- openvswitch_stream_connect(docker_t) --') -- --allow docker_t self:capability { dac_override setgid setpcap setuid sys_admin sys_boot sys_chroot sys_ptrace }; -- --allow docker_t self:process { getcap setcap setexec setpgid setsched signal_perms }; -- --allow docker_t self:netlink_route_socket rw_netlink_socket_perms;; --allow docker_t self:netlink_audit_socket create_netlink_socket_perms; --allow docker_t self:unix_dgram_socket { create_socket_perms sendto }; --allow docker_t self:unix_stream_socket { create_stream_socket_perms connectto }; -- --allow docker_t docker_var_lib_t:dir mounton; --allow docker_t docker_var_lib_t:chr_file mounton; --can_exec(docker_t, docker_var_lib_t) -- --kernel_dontaudit_setsched(docker_t) --kernel_get_sysvipc_info(docker_t) --kernel_request_load_module(docker_t) --kernel_mounton_messages(docker_t) --kernel_mounton_all_proc(docker_t) --kernel_mounton_all_sysctls(docker_t) --kernel_unlabeled_entry_type(spc_t) --kernel_unlabeled_domtrans(docker_t, spc_t) -- --dev_getattr_all(docker_t) --dev_getattr_sysfs_fs(docker_t) --dev_read_urand(docker_t) --dev_read_lvm_control(docker_t) --dev_rw_sysfs(docker_t) --dev_rw_loop_control(docker_t) --dev_rw_lvm_control(docker_t) -- --files_getattr_isid_type_dirs(docker_t) --files_manage_isid_type_dirs(docker_t) --files_manage_isid_type_files(docker_t) --files_manage_isid_type_symlinks(docker_t) --files_manage_isid_type_chr_files(docker_t) --files_manage_isid_type_blk_files(docker_t) --files_exec_isid_files(docker_t) --files_mounton_isid(docker_t) --files_mounton_non_security(docker_t) --files_mounton_isid_type_chr_file(docker_t) -- --fs_mount_all_fs(docker_t) --fs_unmount_all_fs(docker_t) --fs_remount_all_fs(docker_t) --files_mounton_isid(docker_t) --fs_manage_cgroup_dirs(docker_t) --fs_manage_cgroup_files(docker_t) --fs_relabelfrom_xattr_fs(docker_t) --fs_relabelfrom_tmpfs(docker_t) --fs_read_tmpfs_symlinks(docker_t) --fs_list_hugetlbfs(docker_t) -- --term_use_generic_ptys(docker_t) --term_use_ptmx(docker_t) --term_getattr_pty_fs(docker_t) --term_relabel_pty_fs(docker_t) --term_mounton_unallocated_ttys(docker_t) -- --modutils_domtrans_insmod(docker_t) -- --systemd_status_all_unit_files(docker_t) --systemd_start_systemd_services(docker_t) -- --userdom_stream_connect(docker_t) --userdom_search_user_home_content(docker_t) --userdom_read_all_users_state(docker_t) --userdom_relabel_user_home_files(docker_t) --userdom_relabel_user_tmp_files(docker_t) --userdom_relabel_user_tmp_dirs(docker_t) -- --optional_policy(` -- gpm_getattr_gpmctl(docker_t) --') -- --optional_policy(` -- dbus_system_bus_client(docker_t) -- init_dbus_chat(docker_t) -- init_start_transient_unit(docker_t) -- -- optional_policy(` -- systemd_dbus_chat_logind(docker_t) -- ') -- -- optional_policy(` -- firewalld_dbus_chat(docker_t) -- ') --') -- --optional_policy(` -- udev_read_db(docker_t) --') -- --optional_policy(` -- virt_read_config(docker_t) -- virt_exec(docker_t) -- virt_stream_connect(docker_t) -- virt_stream_connect_sandbox(docker_t) -- virt_exec_sandbox_files(docker_t) -- virt_manage_sandbox_files(docker_t) -- virt_relabel_sandbox_filesystem(docker_t) -- virt_transition_svirt_sandbox(docker_t, system_r) -- virt_mounton_sandbox_file(docker_t) --# virt_attach_sandbox_tun_iface(docker_t) -- allow docker_t svirt_sandbox_domain:tun_socket relabelfrom; --') -- --tunable_policy(`docker_connect_any',` -- corenet_tcp_connect_all_ports(docker_t) -- corenet_sendrecv_all_packets(docker_t) -- corenet_tcp_sendrecv_all_ports(docker_t) --') -- --######################################## --# --# spc local policy --# --domain_entry_file(spc_t, docker_share_t) --domain_entry_file(spc_t, docker_var_lib_t) --role system_r types spc_t; -- --domain_entry_file(spc_t, docker_share_t) --domain_entry_file(spc_t, docker_var_lib_t) --domtrans_pattern(docker_t, docker_share_t, spc_t) --domtrans_pattern(docker_t, docker_var_lib_t, spc_t) --allow docker_t spc_t:process { setsched signal_perms }; --ps_process_pattern(docker_t, spc_t) --allow docker_t spc_t:socket_class_set { relabelto relabelfrom }; -- --optional_policy(` -- dbus_chat_system_bus(spc_t) --') -- --optional_policy(` -- unconfined_domain_noaudit(spc_t) --') -- --optional_policy(` -- unconfined_domain(docker_t) --') -- --optional_policy(` -- virt_transition_svirt_sandbox(spc_t, system_r) --') -- --######################################## --# --# docker upstream policy --# -- --optional_policy(` --# domain_stub_named_filetrans_domain() -- gen_require(` -- attribute named_filetrans_domain; -- ') -- -- docker_filetrans_named_content(named_filetrans_domain) --') -- --optional_policy(` -- lvm_stub() -- docker_rw_sem(lvm_t) --') -- --optional_policy(` -- staff_stub() -- docker_stream_connect(staff_t) -- docker_exec(staff_t) --') -- --optional_policy(` -- virt_stub_svirt_sandbox_domain() -- virt_stub_svirt_sandbox_file() -- allow svirt_sandbox_domain self:netlink_kobject_uevent_socket create_socket_perms; -- docker_read_share_files(svirt_sandbox_domain) -- docker_lib_filetrans(svirt_sandbox_domain,svirt_sandbox_file_t, sock_file) -- docker_use_ptys(svirt_sandbox_domain) -- docker_spc_stream_connect(svirt_sandbox_domain) -- fs_list_tmpfs(svirt_sandbox_domain) -- fs_rw_hugetlbfs_files(svirt_sandbox_domain) -- fs_dontaudit_remount_tmpfs(svirt_sandbox_domain) -- dev_dontaudit_mounton_sysfs(svirt_sandbox_domain) -- -- tunable_policy(`virt_sandbox_use_fusefs',` -- fs_manage_fusefs_dirs(svirt_sandbox_domain) -- fs_manage_fusefs_files(svirt_sandbox_domain) -- fs_manage_fusefs_symlinks(svirt_sandbox_domain) -- ') -- gen_require(` -- attribute domain; -- ') -- -- dontaudit svirt_sandbox_domain domain:key {search link}; --') -- --optional_policy(` -- gen_require(` -- type pcp_pmcd_t; -- ') -- docker_manage_lib_files(pcp_pmcd_t) --') -diff --git a/components/engine/hack/make/.build-rpm/docker-engine-selinux-euleros.spec b/components/engine/hack/make/.build-rpm/docker-engine-selinux-euleros.spec -index 0d5189514c..335f123c8b 100644 ---- a/components/engine/hack/make/.build-rpm/docker-engine-selinux-euleros.spec -+++ b/components/engine/hack/make/.build-rpm/docker-engine-selinux-euleros.spec -@@ -29,7 +29,7 @@ URL: https://dockerproject.org - - %global selinuxtype targeted - %global moduletype services --%global modulenames docker -+%global modulenames container - - Requires(post): selinux-policy-base >= %{selinux_policyver}, selinux-policy-targeted >= %{selinux_policyver}, policycoreutils, policycoreutils-python libselinux-utils - BuildRequires: selinux-policy selinux-policy-devel -@@ -79,7 +79,10 @@ if [ $1 -eq 1 ]; then - %{_sbindir}/setsebool -P -N virt_use_nfs=1 virt_sandbox_use_all_caps=1 - fi - %_format MODULES %{_datadir}/selinux/packages/$x.pp.bz2 --%{_sbindir}/semodule -n -s %{selinuxtype} -i $MODULES -+%{_sbindir}/semodule -n -s %{selinuxtype} -r container 2> /dev/null -+%{_sbindir}/semodule -n -s %{selinuxtype} -d docker 2> /dev/null -+%{_sbindir}/semodule -n -s %{selinuxtype} -d gear 2> /dev/null -+%{_sbindir}/semodule -n -X 200 -s %{selinuxtype} -i $MODULES - if %{_sbindir}/selinuxenabled ; then - %{_sbindir}/load_policy - %relabel_files -@@ -97,6 +100,10 @@ if [ $1 -eq 0 ]; then - fi - fi - -+. %{_sysconfdir}/selinux/config -+sed -e "\|container_file_t|h; \${x;s|container_file_t||;{g;t};a\\" -e "container_file_t" -e "}" -i /etc/selinux/${SELINUXTYPE}/contexts/c -+ustomizable_types -+ - %files - %doc LICENSE - %defattr(-,root,root,0755) --- -2.17.1 - diff --git a/patch/0107-restore-cleanup-container-meta-data-when-task.patch b/patch/0107-restore-cleanup-container-meta-data-when-task.patch deleted file mode 100644 index 2510dd9..0000000 --- a/patch/0107-restore-cleanup-container-meta-data-when-task.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 2e5c40ed0ddf40db1ad0e6964e4391ff6bc8e9e1 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Fri, 22 Feb 2019 00:13:07 +0800 -Subject: [PATCH 107/111] restore: cleanup container meta data when - task not exist - -reason: docker_hook:testCE_docker_hook_spec_ABN.081.sh -create container include 2 step: -1. create meta data. -2. create task. -when dockerd restart during creating, it may residue meta while create -task failed. cleanup meta data in restore. - -Change-Id: I80ea1694e3df143c4a5679f680e61d43ddcfe3aa -Signed-off-by: jingrui ---- - components/engine/daemon/daemon.go | 4 ++++ - 5 files changed, 10 insertions(+), 6 deletions(-) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index e26494ed68..c96e28d88d 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -365,6 +365,10 @@ func (daemon *Daemon) restore() error { - } - if !alive { - ec, exitedAt, err = daemon.containerd.DeleteTask(context.Background(), c.ID) -+ if err != nil && errdefs.IsNotFound(err) { -+ err := daemon.containerd.Delete(context.Background(), c.ID) -+ logrus.Infof("cleanup containerd meta for %s error=%v", c.ID, err) -+ } - if err != nil && !errdefs.IsNotFound(err) { - logrus.WithError(err).Errorf("Failed to delete container %s from containerd", c.ID) - return --- -2.17.1 - diff --git a/patch/0108-docker-Fix-can-t-run-image-while-the-image-is.patch b/patch/0108-docker-Fix-can-t-run-image-while-the-image-is.patch deleted file mode 100644 index 90aed12..0000000 --- a/patch/0108-docker-Fix-can-t-run-image-while-the-image-is.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 2b41c414a53011ce005890ff9310bfa5c71fbfbc Mon Sep 17 00:00:00 2001 -From: zhangsong34 -Date: Fri, 18 Jan 2019 17:39:32 +0800 -Subject: [PATCH 108/111] docker: Fix can't run image while the image - is not in `docker images` - -reason:When the layers of image has been damaged, daemon restart fail to load image, -it cause docker can't run the image with unrecognized image ID error. - -Change-Id: I1cecc0dd602cd5a60006ba5c3e6060bd4071fb8e -Signed-off-by: PengFei Yang -Signed-off-by: zhangsong34 ---- - components/engine/daemon/daemon.go | 28 +++++++++++++++++++++++ - components/engine/plugin/backend_linux.go | 4 ++++ - components/engine/reference/store.go | 14 ++++++++++++ - 3 files changed, 46 insertions(+) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index c96e28d88d..7716964304 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -1028,6 +1028,34 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S - return nil, err - } - -+ // delete reference of image not nornamlly loaded to imageStore -+ for _, imageID := range rs.List() { -+ if img, err := imageStore.Get(image.ID(imageID)); err == nil { -+ isExist := false -+ if chainID := img.RootFS.ChainID(); chainID != "" { -+ l, err := layerStores[runtime.GOOS].Get(chainID) -+ if err == nil { -+ layer.ReleaseAndLog(layerStores[runtime.GOOS], l) -+ isExist = true -+ } -+ } else { -+ isExist = true -+ } -+ // If the image not exist locally, delete its reference -+ if !isExist { -+ for _, ref := range rs.References(imageID) { -+ isDelete, err := rs.Delete(ref) -+ if isDelete { -+ logrus.Warnf("Delete reference %s for image id %s from reference store", ref.String(), imageID) -+ } -+ if err != nil { -+ logrus.Warnf("Faild to delete reference %s for image id %s: %v", ref.String(), imageID, err) -+ } -+ } -+ } -+ } -+ } -+ - // No content-addressability migration on Windows as it never supported pre-CA - if runtime.GOOS != "windows" { - migrationStart := time.Now() -diff --git a/components/engine/plugin/backend_linux.go b/components/engine/plugin/backend_linux.go -index 044e14b0cb..e5d3be15ee 100644 ---- a/components/engine/plugin/backend_linux.go -+++ b/components/engine/plugin/backend_linux.go -@@ -490,6 +490,10 @@ func (r *pluginReference) References(id digest.Digest) []reference.Named { - return []reference.Named{r.name} - } - -+func (r *pluginReference) List() []digest.Digest { -+ return []digest.Digest{} -+} -+ - func (r *pluginReference) ReferencesByName(ref reference.Named) []refstore.Association { - return []refstore.Association{ - { -diff --git a/components/engine/reference/store.go b/components/engine/reference/store.go -index e54f772b5e..0df11271a7 100644 ---- a/components/engine/reference/store.go -+++ b/components/engine/reference/store.go -@@ -34,6 +34,7 @@ type Store interface { - AddDigest(ref reference.Canonical, id digest.Digest, force bool) error - Delete(ref reference.Named) (bool, error) - Get(ref reference.Named) (digest.Digest, error) -+ List() []digest.Digest - } - - type store struct { -@@ -274,6 +275,19 @@ func (store *store) References(id digest.Digest) []reference.Named { - return references - } - -+// List retrieves list of image ID, return nil if no image -+func (store *store) List() []digest.Digest { -+ store.mu.RLock() -+ defer store.mu.RUnlock() -+ -+ var ids []digest.Digest -+ for id, _ := range store.referencesByIDCache { -+ ids = append(ids, id) -+ } -+ -+ return ids -+} -+ - // ReferencesByName returns the references for a given repository name. - // If there are no references known for this repository name, - // ReferencesByName returns nil. --- -2.17.1 - diff --git a/patch/0109-graphdriver-add-Checkparent-method.patch b/patch/0109-graphdriver-add-Checkparent-method.patch deleted file mode 100644 index 18d1fde..0000000 --- a/patch/0109-graphdriver-add-Checkparent-method.patch +++ /dev/null @@ -1,199 +0,0 @@ -From f3867c1d93f375441eda73a0c6cb4669fc75f660 Mon Sep 17 00:00:00 2001 -From: zhangsong34 -Date: Sat, 23 Feb 2019 14:39:34 +0800 -Subject: [PATCH 109/111] graphdriver: add Checkparent method - -reason:Use this method to checkout the relationship between -a layer and this parent. It is very useful if graphdriver -stores methdata in its own dirs. - -Change-Id: I07ebe752eb58bc2a027f8a93568b498ad8603713 -Signed-off-by: Liu Hua -Signed-off-by: Deng Guangxing -Signed-off-by: zhangsong34 ---- - .../engine/daemon/graphdriver/aufs/aufs.go | 5 +++++ - .../engine/daemon/graphdriver/btrfs/btrfs.go | 5 +++++ - .../daemon/graphdriver/devmapper/driver.go | 5 +++++ - components/engine/daemon/graphdriver/driver.go | 2 ++ - .../daemon/graphdriver/overlay/overlay.go | 5 +++++ - .../daemon/graphdriver/overlay2/overlay.go | 18 ++++++++++++++++++ - components/engine/daemon/graphdriver/proxy.go | 5 +++++ - .../engine/daemon/graphdriver/vfs/driver.go | 5 +++++ - .../engine/daemon/graphdriver/zfs/zfs.go | 5 +++++ - components/engine/layer/layer_store.go | 5 +++++ - 10 files changed, 60 insertions(+) - -diff --git a/components/engine/daemon/graphdriver/aufs/aufs.go b/components/engine/daemon/graphdriver/aufs/aufs.go -index 303138d48a..eef8387594 100644 ---- a/components/engine/daemon/graphdriver/aufs/aufs.go -+++ b/components/engine/daemon/graphdriver/aufs/aufs.go -@@ -235,6 +235,11 @@ func (a *Driver) GetAll() []string { - return []string{} - } - -+// CheckParent not implemented -+func (a *Driver) CheckParent(id, parent string) error { -+ return nil -+} -+ - // CreateReadWrite creates a layer that is writable for use as a container - // file system. - func (a *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error { -diff --git a/components/engine/daemon/graphdriver/btrfs/btrfs.go b/components/engine/daemon/graphdriver/btrfs/btrfs.go -index d04ce10be9..7d1f9dc2b1 100644 ---- a/components/engine/daemon/graphdriver/btrfs/btrfs.go -+++ b/components/engine/daemon/graphdriver/btrfs/btrfs.go -@@ -172,6 +172,11 @@ func (a *Driver) GetAll() []string { - return []string{} - } - -+// CheckParent not implemented -+func (d *Driver) CheckParent(id, parent string) error { -+ return nil -+} -+ - // Cleanup unmounts the home directory. - func (d *Driver) Cleanup() error { - err := d.subvolDisableQuota() -diff --git a/components/engine/daemon/graphdriver/devmapper/driver.go b/components/engine/daemon/graphdriver/devmapper/driver.go -index a56b26bc8f..1eade3aba5 100644 ---- a/components/engine/daemon/graphdriver/devmapper/driver.go -+++ b/components/engine/daemon/graphdriver/devmapper/driver.go -@@ -131,6 +131,11 @@ func (a *Driver) GetAll() []string { - return []string{} - } - -+// CheckParent not implemented -+func (d *Driver) CheckParent(id, parent string) error { -+ return nil -+} -+ - // Cleanup unmounts a device. - func (d *Driver) Cleanup() error { - err := d.DeviceSet.Shutdown(d.home) -diff --git a/components/engine/daemon/graphdriver/driver.go b/components/engine/daemon/graphdriver/driver.go -index 672257a9b5..9976571cde 100644 ---- a/components/engine/daemon/graphdriver/driver.go -+++ b/components/engine/daemon/graphdriver/driver.go -@@ -80,6 +80,8 @@ type ProtoDriver interface { - Cleanup() error - // GetAll returns all the mountid exists in this driver - GetAll() []string -+ // CheckParent checks whether the parent is the right lower layer -+ CheckParent(id, parent string) error - } - - // DiffDriver is the interface to use to implement graph diffs -diff --git a/components/engine/daemon/graphdriver/overlay/overlay.go b/components/engine/daemon/graphdriver/overlay/overlay.go -index d59a6dfc83..7dbeec5376 100644 ---- a/components/engine/daemon/graphdriver/overlay/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay/overlay.go -@@ -276,6 +276,11 @@ func (d *Driver) Cleanup() error { - return mount.RecursiveUnmount(d.home) - } - -+// CheckParent not implemented -+func (d *Driver) CheckParent(id, parent string) error { -+ return nil -+} -+ - // CreateReadWrite creates a layer that is writable for use as a container - // file system. - func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error { -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index 1a3c9c9d67..7fd3fab645 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -360,6 +360,24 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) { - return metadata, nil - } - -+// CheckParent checks the relationship between id and parent -+func (d *Driver) CheckParent(id, parent string) error { -+ metadata, err := d.GetMetadata(id) -+ if err != nil { -+ return err -+ } -+ lowerDirs, exist := metadata["LowerDir"] -+ if !exist { -+ return fmt.Errorf("%s does not have lower layers", id) -+ } -+ -+ if !strings.Contains(lowerDirs, parent) { -+ return fmt.Errorf("Lower layer(%s) of %s does not exist", parent, id) -+ } -+ return nil -+ -+} -+ - // Cleanup any state created by overlay which should be cleaned when daemon - // is being shutdown. For now, we just have to unmount the bind mounted - // we had created. -diff --git a/components/engine/daemon/graphdriver/proxy.go b/components/engine/daemon/graphdriver/proxy.go -index 6c132d40a8..990f9b4d4e 100644 ---- a/components/engine/daemon/graphdriver/proxy.go -+++ b/components/engine/daemon/graphdriver/proxy.go -@@ -96,6 +96,11 @@ func (d *graphDriverProxy) GetAll() []string { - return []string{} - } - -+// CheckParent not implemented -+func (a *graphDriverProxy) CheckParent(id, parent string) error { -+ return nil -+} -+ - func (d *graphDriverProxy) CreateReadWrite(id, parent string, opts *CreateOpts) error { - return d.create("GraphDriver.CreateReadWrite", id, parent, opts) - } -diff --git a/components/engine/daemon/graphdriver/vfs/driver.go b/components/engine/daemon/graphdriver/vfs/driver.go -index 8c2947d9ee..6b9e92e16c 100644 ---- a/components/engine/daemon/graphdriver/vfs/driver.go -+++ b/components/engine/daemon/graphdriver/vfs/driver.go -@@ -69,6 +69,11 @@ func (a *Driver) GetAll() []string { - return []string{} - } - -+// CheckParent not implemented -+func (d *Driver) CheckParent(id, parent string) error { -+ return nil -+} -+ - // Cleanup is used to implement graphdriver.ProtoDriver. There is no cleanup required for this driver. - func (d *Driver) Cleanup() error { - return nil -diff --git a/components/engine/daemon/graphdriver/zfs/zfs.go b/components/engine/daemon/graphdriver/zfs/zfs.go -index e1e2d0d823..e5958093db 100644 ---- a/components/engine/daemon/graphdriver/zfs/zfs.go -+++ b/components/engine/daemon/graphdriver/zfs/zfs.go -@@ -232,6 +232,11 @@ func (a *Driver) GetAll() []string { - return []string{} - } - -+// CheckParent not implemented -+func (d *Driver) CheckParent(id, parent string) error { -+ return nil -+} -+ - func (d *Driver) cloneFilesystem(name, parentName string) error { - snapshotName := fmt.Sprintf("%d", time.Now().Nanosecond()) - parentDataset := zfs.Dataset{Name: parentName} -diff --git a/components/engine/layer/layer_store.go b/components/engine/layer/layer_store.go -index b6fc45e655..c514ed802a 100644 ---- a/components/engine/layer/layer_store.go -+++ b/components/engine/layer/layer_store.go -@@ -192,6 +192,11 @@ func (ls *layerStore) loadLayer(layer ChainID) (l *roLayer, err error) { - if err != nil { - return nil, err - } -+ -+ err = ls.driver.CheckParent(cacheID, p.cacheID) -+ if err != nil { -+ return nil, err -+ } - cl.parent = p - } else { - _, err := ls.driver.GetMetadata(cacheID) --- -2.17.1 - diff --git a/patch/0110-docker-Fix-can-t-pull-image-while-the-image-i.patch b/patch/0110-docker-Fix-can-t-pull-image-while-the-image-i.patch deleted file mode 100644 index e6bd215..0000000 --- a/patch/0110-docker-Fix-can-t-pull-image-while-the-image-i.patch +++ /dev/null @@ -1,139 +0,0 @@ -From d3cd69071d70e749d0561a6ebedf089c9d973d76 Mon Sep 17 00:00:00 2001 -From: zhangsong34 -Date: Sat, 23 Feb 2019 14:42:44 +0800 -Subject: [PATCH 110/111] docker: Fix can't pull image while the image - is not in `docker images` - -reason:When the layers of image has been damaged, daemon restart fail to load image,it cause -docker pull can't normally download the image. - -delete image reference from repositories.json if no image configfound - cherry-pick from docker 1.11.2: ca25e85 - -Change-Id: Iab6081b34d76bc0bf49414d041115db39c1a256e -Signed-off-by: PengFei Yang yangpengfei4@huawei.com -Signed-off-by: zhangsong34 ---- - components/engine/daemon/daemon.go | 27 +++++++++++-------- - components/engine/daemon/images/image_pull.go | 2 ++ - components/engine/distribution/config.go | 2 ++ - components/engine/distribution/pull_v2.go | 20 +++++++++++--- - 4 files changed, 36 insertions(+), 15 deletions(-) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 7716964304..84a28df78a 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -1029,9 +1029,10 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S - } - - // delete reference of image not nornamlly loaded to imageStore -+ var isExist bool - for _, imageID := range rs.List() { - if img, err := imageStore.Get(image.ID(imageID)); err == nil { -- isExist := false -+ isExist = false - if chainID := img.RootFS.ChainID(); chainID != "" { - l, err := layerStores[runtime.GOOS].Get(chainID) - if err == nil { -@@ -1041,19 +1042,23 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S - } else { - isExist = true - } -- // If the image not exist locally, delete its reference -- if !isExist { -- for _, ref := range rs.References(imageID) { -- isDelete, err := rs.Delete(ref) -- if isDelete { -- logrus.Warnf("Delete reference %s for image id %s from reference store", ref.String(), imageID) -- } -- if err != nil { -- logrus.Warnf("Faild to delete reference %s for image id %s: %v", ref.String(), imageID, err) -- } -+ } else { -+ logrus.Warnf("Failed to get image configration for image id %s, error: %s", imageID, err) -+ } -+ -+ // If the image not exist locally, delete its reference -+ if !isExist { -+ for _, ref := range rs.References(imageID) { -+ isDelete, err := rs.Delete(ref) -+ if isDelete { -+ logrus.Warnf("Delete reference %s for image id %s from reference store", ref.String(), imageID) -+ } -+ if err != nil { -+ logrus.Warnf("Faild to delete reference %s for image id %s: %v", ref.String(), imageID, err) - } - } - } -+ - } - - // No content-addressability migration on Windows as it never supported pre-CA -diff --git a/components/engine/daemon/images/image_pull.go b/components/engine/daemon/images/image_pull.go -index 3e6b433037..1c57c80c3c 100644 ---- a/components/engine/daemon/images/image_pull.go -+++ b/components/engine/daemon/images/image_pull.go -@@ -3,6 +3,7 @@ package images // import "github.com/docker/docker/daemon/images" - import ( - "context" - "io" -+ "runtime" - "strings" - "time" - -@@ -73,6 +74,7 @@ func (i *ImageService) pullImageWithReference(ctx context.Context, ref reference - RegistryService: i.registryService, - ImageEventLogger: i.LogImageEvent, - MetadataStore: i.distributionMetadataStore, -+ LayerStore: i.layerStores[runtime.GOOS], - ImageStore: distribution.NewImageConfigStoreFromStore(i.imageStore), - ReferenceStore: i.referenceStore, - }, -diff --git a/components/engine/distribution/config.go b/components/engine/distribution/config.go -index 438051c296..211d4f049d 100644 ---- a/components/engine/distribution/config.go -+++ b/components/engine/distribution/config.go -@@ -42,6 +42,8 @@ type Config struct { - // MetadataStore is the storage backend for distribution-specific - // metadata. - MetadataStore metadata.Store -+ // LayerStore manages layers. -+ LayerStore layer.Store - // ImageStore manages images. - ImageStore ImageConfigStore - // ReferenceStore manages tags. This value is optional, when excluded -diff --git a/components/engine/distribution/pull_v2.go b/components/engine/distribution/pull_v2.go -index 8f05cfa0b2..2c90e2f93f 100644 ---- a/components/engine/distribution/pull_v2.go -+++ b/components/engine/distribution/pull_v2.go -@@ -555,10 +555,22 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s - } - - target := mfst.Target() -- if _, err := p.config.ImageStore.Get(target.Digest); err == nil { -- // If the image already exists locally, no need to pull -- // anything. -- return target.Digest, manifestDigest, nil -+ if img, err := p.config.ImageStore.Get(target.Digest); err == nil { -+ rootfs, err := p.config.ImageStore.RootFSFromConfig(img) -+ if err == nil { -+ if chainID := rootfs.ChainID(); chainID != "" { -+ l, err := p.config.LayerStore.Get(chainID) -+ if err == nil { -+ layer.ReleaseAndLog(p.config.LayerStore, l) -+ // If the image already exists locally, no need to pull anything. -+ return target.Digest, manifestDigest, nil -+ } -+ } else { -+ return target.Digest, manifestDigest, nil -+ } -+ } else { -+ return target.Digest, manifestDigest, nil -+ } - } - - var descriptors []xfer.DownloadDescriptor --- -2.17.1 - diff --git a/patch/0112-docker-overlay2-quota-control-bugfix.patch b/patch/0112-docker-overlay2-quota-control-bugfix.patch deleted file mode 100644 index dde7ef5..0000000 --- a/patch/0112-docker-overlay2-quota-control-bugfix.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 3e057e395eae95686693584aff1e5236e30ff437 Mon Sep 17 00:00:00 2001 -From: zhangsong34 -Date: Tue, 5 Mar 2019 22:39:26 +0800 -Subject: [PATCH] docker: overlay2 quota control bugfix - -reason:overlay2 quota control bugfix. - -Change-Id: I0e016fdb7619e8213d92c6eb2d5ba67ab606968e -Signed-off-by: zhangsong34 ---- - .../engine/daemon/graphdriver/overlay2/overlay.go | 18 +++++++++++------- - 1 file changed, 11 insertions(+), 7 deletions(-) - -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index 7fd3fab..a755c86 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -452,15 +452,19 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr - } - - if driver.options.quota.Size > 0 { -- // Set container disk quota limit -- if err := d.quotaCtl.SetQuota(dir, driver.options.quota); err != nil { -- return err -+ if d.quotaCtl != nil { -+ // Set container disk quota limit -+ if err := d.quotaCtl.SetQuota(dir, driver.options.quota); err != nil { -+ return err -+ } - } - } - } else if d.options.quota.Size > 0 { -- // docker run not specified quota size, but dockerd does, so limits it also -- if err := d.quotaCtl.SetQuota(dir, d.options.quota); err != nil { -- return err -+ if d.quotaCtl != nil { -+ // docker run not specified quota size, but dockerd does, so limits it also -+ if err := d.quotaCtl.SetQuota(dir, d.options.quota); err != nil { -+ return err -+ } - } - } - --- -1.8.3.1 - diff --git a/patch/0114-docker-mask-internal-proc-files.patch b/patch/0114-docker-mask-internal-proc-files.patch deleted file mode 100644 index 9bdbe9b..0000000 --- a/patch/0114-docker-mask-internal-proc-files.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 9074b27c256b5a65883be587c8637dc3926016eb Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Tue, 9 Apr 2019 16:42:47 +0800 -Subject: [PATCH] docker: mask internal proc files - -Change-Id: I249d3f32bac586c37f97f0861afda0ddbfd7561e -Signed-off-by: jingrui ---- - .../github.com/containerd/containerd/oci/spec.go | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/components/cli/vendor/github.com/containerd/containerd/oci/spec.go b/components/cli/vendor/github.com/containerd/containerd/oci/spec.go -index 6fb31e454c..bc5cc45c16 100644 ---- a/components/cli/vendor/github.com/containerd/containerd/oci/spec.go -+++ b/components/cli/vendor/github.com/containerd/containerd/oci/spec.go -@@ -208,14 +208,26 @@ func populateDefaultUnixSpec(ctx context.Context, s *Spec, id string) error { - Linux: &specs.Linux{ - MaskedPaths: []string{ - "/proc/acpi", -+ "/proc/config.gz", - "/proc/kcore", - "/proc/keys", - "/proc/latency_stats", - "/proc/timer_list", - "/proc/timer_stats", - "/proc/sched_debug", -- "/sys/firmware", - "/proc/scsi", -+ "/proc/signo", -+ "/proc/sig_catch", -+ "/proc/kbox", -+ "/proc/oom_extend", -+ "/proc/fdthreshold", -+ "/proc/fdstat", -+ "/proc/fdenable", -+ "/proc/files_panic_enable", -+ "/sys/firmware", -+ "/proc/cpuirqstat", -+ "/proc/memstat", -+ "/proc/iomem_ext", - }, - ReadonlyPaths: []string{ - "/proc/asound", --- -2.17.1 - diff --git a/patch/0115-docker-enable-bep-ldflags.patch b/patch/0115-docker-enable-bep-ldflags.patch deleted file mode 100644 index 871565c..0000000 --- a/patch/0115-docker-enable-bep-ldflags.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 3fc47d106cc8648c6a2cb11ae68789b35dac10e2 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 11 Apr 2019 23:43:59 +0800 -Subject: [PATCH] docker: enable bep ldflags - -Change-Id: Ib1a6f2a6a1c45f8eba4811e38469c26c6117128b -Signed-off-by: jingrui ---- - components/cli/scripts/build/dynbinary | 7 ++++++- - components/engine/hack/make/.binary | 4 ++++ - 2 files changed, 10 insertions(+), 1 deletion(-) - mode change 100644 => 100755 components/engine/hack/make/.binary - -diff --git a/components/cli/scripts/build/dynbinary b/components/cli/scripts/build/dynbinary -index 4feb7e71d8..c9f33be17b 100755 ---- a/components/cli/scripts/build/dynbinary -+++ b/components/cli/scripts/build/dynbinary -@@ -9,6 +9,11 @@ source ./scripts/build/.variables - - echo "Building dynamically linked $TARGET" - export CGO_ENABLED=1 --go build -o "${TARGET}" -tags pkcs11 --ldflags "${LDFLAGS}" -buildmode=pie "${SOURCE}" -+ -+BEP_DIR=/tmp/docker-build-bep -+BEP_FLAGS="-tmpdir=$BEP_DIR" -+mkdir -p $BEP_DIR -+ -+go build -o "${TARGET}" -tags pkcs11 --ldflags " $BEP_FLAGS ${LDFLAGS}" -buildmode=pie "${SOURCE}" - - ln -sf "$(basename "${TARGET}")" build/docker -diff --git a/components/engine/hack/make/.binary b/components/engine/hack/make/.binary -old mode 100644 -new mode 100755 -index 010c2c11da..7a203edf40 ---- a/components/engine/hack/make/.binary -+++ b/components/engine/hack/make/.binary -@@ -60,10 +60,14 @@ case "$(go env GOOS)/$(go env GOARCH)" in - esac - - echo "Building: $DEST/$BINARY_FULLNAME" -+BEP_DIR=/tmp/dockerd-build-bep -+BEP_FLAGS="-tmpdir=$BEP_DIR" -+mkdir -p $BEP_DIR - go build \ - -o "$DEST/$BINARY_FULLNAME" \ - "${BUILDFLAGS[@]}" \ - -ldflags " -+ $BEP_FLAGS - $LDFLAGS - $LDFLAGS_STATIC_DOCKER - $DOCKER_LDFLAGS --- -2.17.1 - diff --git a/patch/0116-docker-build-with-relro-flags.patch b/patch/0116-docker-build-with-relro-flags.patch deleted file mode 100644 index bff1397..0000000 --- a/patch/0116-docker-build-with-relro-flags.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 82d288bb3b3457eaecf78510c9ecd86f91beaf2e Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Tue, 16 Apr 2019 10:34:11 +0800 -Subject: [PATCH] docker: build with relro flags - -Change-Id: I227dd6dfcf4560671abd4a7e9362485591686933 -Signed-off-by: jingrui ---- - components/cli/scripts/build/dynbinary | 2 +- - components/engine/hack/make/.binary | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/components/cli/scripts/build/dynbinary b/components/cli/scripts/build/dynbinary -index c9f33be17b..db91da1a28 100755 ---- a/components/cli/scripts/build/dynbinary -+++ b/components/cli/scripts/build/dynbinary -@@ -14,6 +14,6 @@ BEP_DIR=/tmp/docker-build-bep - BEP_FLAGS="-tmpdir=$BEP_DIR" - mkdir -p $BEP_DIR - --go build -o "${TARGET}" -tags pkcs11 --ldflags " $BEP_FLAGS ${LDFLAGS}" -buildmode=pie "${SOURCE}" -+go build -o "${TARGET}" -tags pkcs11 --ldflags " -extldflags=-zrelro -extldflags=-znow $BEP_FLAGS ${LDFLAGS}" -buildmode=pie "${SOURCE}" - - ln -sf "$(basename "${TARGET}")" build/docker -diff --git a/components/engine/hack/make/.binary b/components/engine/hack/make/.binary -index 7a203edf40..578e8aea5d 100755 ---- a/components/engine/hack/make/.binary -+++ b/components/engine/hack/make/.binary -@@ -67,7 +67,7 @@ go build \ - -o "$DEST/$BINARY_FULLNAME" \ - "${BUILDFLAGS[@]}" \ - -ldflags " -- $BEP_FLAGS -+ -extldflags=-zrelro -extldflags=-znow $BEP_FLAGS - $LDFLAGS - $LDFLAGS_STATIC_DOCKER - $DOCKER_LDFLAGS --- -2.17.1 - diff --git a/patch/0117-healthcheck-synchronize-the-healthcheck-statu.patch b/patch/0117-healthcheck-synchronize-the-healthcheck-statu.patch deleted file mode 100644 index 2b6390d..0000000 --- a/patch/0117-healthcheck-synchronize-the-healthcheck-statu.patch +++ /dev/null @@ -1,34 +0,0 @@ -From c91cf6bd930293e4eadcd2a20c704b589ab0b371 Mon Sep 17 00:00:00 2001 -From: zhangyu235 -Date: Thu, 18 Apr 2019 16:04:18 +0800 -Subject: [PATCH] healthcheck: synchronize the healthcheck status of - containers when restart daemon - -Change-Id: I6bcced3c69deb9e1a88fff229f344e4ab28f80b2 ---- - components/engine/daemon/daemon.go | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 84a28df..041e714 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -427,6 +427,15 @@ func (daemon *Daemon) restore() error { - c.Unlock() - } - -+ if getProbe(c) != nil { -+ c.Lock() -+ if err := c.CheckpointTo(daemon.containersReplica); err != nil { -+ logrus.WithError(err).WithField("container", c.ID). -+ Error("Failed to checkpoint container state") -+ } -+ c.Unlock() -+ } -+ - // we call Mount and then Unmount to get BaseFs of the container - if err := daemon.Mount(c); err != nil { - // The mount is unlikely to fail. However, in case mount fails --- -2.7.4.3 - diff --git a/patch/0118-docker-fix-opened-file-not-close.patch b/patch/0118-docker-fix-opened-file-not-close.patch deleted file mode 100644 index 855f456..0000000 --- a/patch/0118-docker-fix-opened-file-not-close.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 2fb693565515e5aac7ba69b93320edb39f3c7fbb Mon Sep 17 00:00:00 2001 -From: lixiang172 -Date: Fri, 19 Apr 2019 17:38:43 +0800 -Subject: [PATCH] docker: fix opened file not close - -Change-Id: Ibf832b1971a85c85de8dfc0587f5d8762e70c16e -Signed-off-by: lixiang172 ---- - components/cli/internal/pkg/containerized/proxy.go | 1 + - components/engine/daemon/logger/loggerutils/logfile.go | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/components/cli/internal/pkg/containerized/proxy.go b/components/cli/internal/pkg/containerized/proxy.go -index ed195db..f88be52 100644 ---- a/components/cli/internal/pkg/containerized/proxy.go -+++ b/components/cli/internal/pkg/containerized/proxy.go -@@ -57,6 +57,7 @@ func storeConfig(name string, cfg *proxyConfig) error { - if err != nil { - return err - } -+ defer fd.Close() - err = fd.Truncate(0) - if err != nil { - return err -diff --git a/components/engine/daemon/logger/loggerutils/logfile.go b/components/engine/daemon/logger/loggerutils/logfile.go -index 623f78f..3b30ce2 100644 ---- a/components/engine/daemon/logger/loggerutils/logfile.go -+++ b/components/engine/daemon/logger/loggerutils/logfile.go -@@ -118,6 +118,7 @@ func NewLogFile(logPath string, capacity int64, maxFiles int, compress bool, mar - - size, err := log.Seek(0, os.SEEK_END) - if err != nil { -+ log.Close() - return nil, err - } - --- -1.8.3.1 - diff --git a/patch/0119-docker-set-makefile-buildid.patch b/patch/0119-docker-set-makefile-buildid.patch deleted file mode 100644 index 37ffe54..0000000 --- a/patch/0119-docker-set-makefile-buildid.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 66e09ef9a29c4a24ca7771fa120cd35b0769a70d Mon Sep 17 00:00:00 2001 -From: lixiang172 -Date: Tue, 23 Apr 2019 12:28:40 +0800 -Subject: [PATCH] docker: set makefile buildid - -reason: set makefile buildid - -Signed-off-by: lixiang172 ---- - components/cli/scripts/build/dynbinary | 2 +- - components/engine/hack/make/.binary | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/components/cli/scripts/build/dynbinary b/components/cli/scripts/build/dynbinary -index db91da1..2442166 100755 ---- a/components/cli/scripts/build/dynbinary -+++ b/components/cli/scripts/build/dynbinary -@@ -14,6 +14,6 @@ BEP_DIR=/tmp/docker-build-bep - BEP_FLAGS="-tmpdir=$BEP_DIR" - mkdir -p $BEP_DIR - --go build -o "${TARGET}" -tags pkcs11 --ldflags " -extldflags=-zrelro -extldflags=-znow $BEP_FLAGS ${LDFLAGS}" -buildmode=pie "${SOURCE}" -+go build -o "${TARGET}" -tags pkcs11 --ldflags " -buildid=IdByIsula -extldflags=-zrelro -extldflags=-znow $BEP_FLAGS ${LDFLAGS}" -buildmode=pie "${SOURCE}" - - ln -sf "$(basename "${TARGET}")" build/docker -diff --git a/components/engine/hack/make/.binary b/components/engine/hack/make/.binary -index 578e8ae..f76b6f7 100755 ---- a/components/engine/hack/make/.binary -+++ b/components/engine/hack/make/.binary -@@ -67,7 +67,7 @@ go build \ - -o "$DEST/$BINARY_FULLNAME" \ - "${BUILDFLAGS[@]}" \ - -ldflags " -- -extldflags=-zrelro -extldflags=-znow $BEP_FLAGS -+ -buildid=IdByIsula -extldflags=-zrelro -extldflags=-znow $BEP_FLAGS - $LDFLAGS - $LDFLAGS_STATIC_DOCKER - $DOCKER_LDFLAGS --- -1.8.3.1 - diff --git a/patch/0120-docker-fix-docker-logs-hangs-when-using-journ.patch b/patch/0120-docker-fix-docker-logs-hangs-when-using-journ.patch deleted file mode 100644 index b3823e7..0000000 --- a/patch/0120-docker-fix-docker-logs-hangs-when-using-journ.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 34112ccb2adef535a339d32a517976f7674b22ee Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Fri, 10 May 2019 02:59:48 +0800 -Subject: [PATCH] docker: fix docker logs hangs when using journald - -reason: Fix when using journald as log-driver, docker logs process hangs after container stops. - -Change-Id: I41832b77b0282376c6b2ffc77978c76a617361b8 -Signed-off-by: xiadanni1 ---- - components/engine/daemon/logger/journald/read.go | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/components/engine/daemon/logger/journald/read.go b/components/engine/daemon/logger/journald/read.go -index cadb97f..d4b1c75 100644 ---- a/components/engine/daemon/logger/journald/read.go -+++ b/components/engine/daemon/logger/journald/read.go -@@ -303,6 +303,9 @@ func (s *journald) followJournal(logWatcher *logger.LogWatcher, j *C.sd_journal, - // Notify the other goroutine that its work is done. - C.close(pfd[1]) - cursor = <-newCursor -+ case <-logWatcher.WatchProducerGone(): -+ C.close(pfd[1]) -+ cursor = <-newCursor - } - - return cursor --- -1.8.3.1 - diff --git a/patch/0121-docker-add-start-timeout-for-container.patch b/patch/0121-docker-add-start-timeout-for-container.patch deleted file mode 100644 index 474464d..0000000 --- a/patch/0121-docker-add-start-timeout-for-container.patch +++ /dev/null @@ -1,73 +0,0 @@ -From f669a33c163fb53e64d5b0582418a38662927c87 Mon Sep 17 00:00:00 2001 -From: lixiang172 -Date: Fri, 10 May 2019 16:52:19 +0800 -Subject: [PATCH] docker: add start-timeout for container - -Change-Id: Ife8660b3fc665535086bcb0ea56454c7f5147140 -Signed-off-by: lixiang172 ---- - components/engine/cmd/dockerd/config_unix.go | 1 + - components/engine/cmd/dockerd/daemon.go | 19 +++++++++++++++++++ - components/engine/daemon/config/config_unix.go | 1 + - 3 files changed, 21 insertions(+) - -diff --git a/components/engine/cmd/dockerd/config_unix.go b/components/engine/cmd/dockerd/config_unix.go -index 2dbd84b..8d38d75 100644 ---- a/components/engine/cmd/dockerd/config_unix.go -+++ b/components/engine/cmd/dockerd/config_unix.go -@@ -46,5 +46,6 @@ func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) { - flags.BoolVar(&conf.NoNewPrivileges, "no-new-privileges", false, "Set no-new-privileges by default for new containers") - flags.StringVar(&conf.IpcMode, "default-ipc-mode", config.DefaultIpcMode, `Default mode for containers ipc ("shareable" | "private")`) - flags.Var(&conf.NetworkConfig.DefaultAddressPools, "default-address-pool", "Default address pools for node specific local networks") -+ flags.StringVar(&conf.StartTimeout, "start-timeout", "2m", "Timeout duration for waiting on a container to start before it is killed") - - } -diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go -index 8395373..ea00c56 100644 ---- a/components/engine/cmd/dockerd/daemon.go -+++ b/components/engine/cmd/dockerd/daemon.go -@@ -94,6 +94,9 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { - logrus.Warn("Running experimental build") - } - -+ if err := cli.setRuntimeStartTimeout(); err != nil { -+ return err -+ } - logrus.SetFormatter(&logrus.TextFormatter{ - TimestampFormat: jsonmessage.RFC3339NanoFixed, - DisableColors: cli.Config.RawLogs, -@@ -670,3 +673,19 @@ func systemContainerdRunning() bool { - _, err := os.Lstat(containerddefaults.DefaultAddress) - return err == nil - } -+ -+func (cli *DaemonCli) setRuntimeStartTimeout() error { -+ minRuntimeTimeout := 30 * time.Second -+ maxRuntimeTimeout := 10 * time.Minute -+ env := "DOCKER_RUNTIME_START_TIMEOUT" -+ defaultRuntimeTimeout := "2m" -+ timeout := cli.Config.StartTimeout -+ if timeout != "" { -+ timeParse, err := time.ParseDuration(timeout) -+ if err != nil || timeParse < minRuntimeTimeout || timeParse > maxRuntimeTimeout { -+ return fmt.Errorf("start-timeout invalid value: %s, should in range [%s-%s]", timeout, minRuntimeTimeout, maxRuntimeTimeout) -+ } -+ return os.Setenv(env, timeout) -+ } -+ return os.Setenv(env, defaultRuntimeTimeout) -+} -diff --git a/components/engine/daemon/config/config_unix.go b/components/engine/daemon/config/config_unix.go -index 5ed6abd..d094269 100644 ---- a/components/engine/daemon/config/config_unix.go -+++ b/components/engine/daemon/config/config_unix.go -@@ -37,6 +37,7 @@ type Config struct { - ShmSize opts.MemBytes `json:"default-shm-size,omitempty"` - NoNewPrivileges bool `json:"no-new-privileges,omitempty"` - IpcMode string `json:"default-ipc-mode,omitempty"` -+ StartTimeout string `json:"start-timeout,omitempty"` - // ResolvConf is the path to the configuration of the host resolver - ResolvConf string `json:"resolv-conf,omitempty"` - } --- -1.8.3.1 - diff --git a/patch/0122-cleanup-local-db-on-first-start-after-os-star.patch b/patch/0122-cleanup-local-db-on-first-start-after-os-star.patch deleted file mode 100644 index da5a418..0000000 --- a/patch/0122-cleanup-local-db-on-first-start-after-os-star.patch +++ /dev/null @@ -1,87 +0,0 @@ -From f7263dbc15c9730bd5dd562790d17607bbd6caec Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Tue, 14 May 2019 12:13:46 +0800 -Subject: [PATCH] cleanup local-db on first start after os start - -Change-Id: I8ed28bbdd4d7d87211339e8d1d752f435c999789 -Signed-off-by: jingrui ---- - components/engine/daemon/daemon.go | 55 ++++++++++++++++++++++++++++++ - 1 file changed, 55 insertions(+) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 041e7142f1..2d5051412e 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -509,6 +509,8 @@ func (daemon *Daemon) restore() error { - logrus.Errorf("removeRedundantMounts failed %v", err) - } - -+ daemon.cleanupLocalDBs() -+ - containerIDs := make(map[string]struct{}) - for cid, _ := range containers { - containerIDs[cid] = struct{}{} -@@ -609,6 +611,59 @@ func (daemon *Daemon) restore() error { - return nil - } - -+func (daemon *Daemon) cleanupLocalDB(db string) { -+ _, err := os.Stat(db) -+ if err == nil { -+ err = os.Remove(db) -+ logrus.Infof("cleanup DB %s error=%v", db, err) -+ } -+} -+ -+// DB files may corrupted on exception poweroff but can be rebuild at run time, -+// so we can remove DB files on OS starts avoid daemon can not startup. -+func (daemon *Daemon) cleanupLocalDBs() { -+ // check db lock is exist, do nothing if file is existed -+ dbLockPath := filepath.Join(daemon.configStore.ExecRoot, "dblock") -+ _, err := os.Stat(dbLockPath) -+ if err == nil { -+ return -+ } -+ if !os.IsNotExist(err) { -+ logrus.Errorf("stat dblock failed %v", err) -+ return -+ } -+ ioutil.WriteFile(dbLockPath, []byte{}, 0600) -+ -+ removeAllDB := func() { -+ daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "builder/fscache.db")) -+ daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "volumes/metadata.db")) -+ daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "network/files/local-kv.db")) -+ // daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) -+ daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "accelerator/accel.db")) -+ daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "buildkit/metadata.db")) -+ daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "buildkit/cache.db")) -+ daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "buildkit/snapshots.db")) -+ } -+ -+ if daemon.containers == nil { -+ logrus.Warnf("nil containers, cleanup local DB after OS start ...") -+ removeAllDB() -+ return -+ } -+ -+ ls, err := daemon.Containers(&types.ContainerListOptions{}) -+ if err != nil { -+ logrus.Errorf("list containers failed %v", err) -+ return -+ } -+ -+ if len(ls) == 0 { -+ logrus.Warnf("no running containers, cleanup local DB after OS start ...") -+ removeAllDB() -+ return -+ } -+} -+ - // RestartSwarmContainers restarts any autostart container which has a - // swarm endpoint. - func (daemon *Daemon) RestartSwarmContainers() { --- -2.17.1 - diff --git a/patch/0123-docker-support-exit-on-unhealthy.patch b/patch/0123-docker-support-exit-on-unhealthy.patch deleted file mode 100644 index 9b6ad92..0000000 --- a/patch/0123-docker-support-exit-on-unhealthy.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 3a9b96e32c226fefee5e410ee9fcf0376bf89f4d Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 5 Jun 2019 18:48:12 +0800 -Subject: [PATCH] docker support exit on unhealthy - -Change-Id: Ie4ae17e976ac2a4981fdb6f891987ffe3ea900a6 -Signed-off-by: jingrui ---- - components/cli/cli/command/container/opts.go | 3 +++ - .../github.com/docker/docker/api/types/container/config.go | 3 +++ - components/engine/api/types/container/config.go | 3 +++ - components/engine/daemon/health.go | 6 ++++++ - 4 files changed, 15 insertions(+) - -diff --git a/components/cli/cli/command/container/opts.go b/components/cli/cli/command/container/opts.go -index f009cd0ea1..00da8fc570 100644 ---- a/components/cli/cli/command/container/opts.go -+++ b/components/cli/cli/command/container/opts.go -@@ -121,6 +121,7 @@ type containerOptions struct { - healthTimeout time.Duration - healthStartPeriod time.Duration - healthRetries int -+ healthExitOnUnhealthy bool - runtime string - autoRemove bool - init bool -@@ -239,6 +240,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { - flags.StringVar(&copts.healthCmd, "health-cmd", "", "Command to run to check health") - flags.DurationVar(&copts.healthInterval, "health-interval", 0, "Time between running the check (ms|s|m|h) (default 0s)") - flags.IntVar(&copts.healthRetries, "health-retries", 0, "Consecutive failures needed to report unhealthy") -+ flags.BoolVar(&copts.healthExitOnUnhealthy, "health-exit-on-unhealthy", false, "Shut down a container if it becomes Unhealthy") - flags.DurationVar(&copts.healthTimeout, "health-timeout", 0, "Maximum time to allow one check to run (ms|s|m|h) (default 0s)") - flags.DurationVar(&copts.healthStartPeriod, "health-start-period", 0, "Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s)") - flags.SetAnnotation("health-start-period", "version", []string{"1.29"}) -@@ -530,6 +532,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err - Timeout: copts.healthTimeout, - StartPeriod: copts.healthStartPeriod, - Retries: copts.healthRetries, -+ ExitOnUnhealthy: copts.healthExitOnUnhealthy, - } - } - -diff --git a/components/cli/vendor/github.com/docker/docker/api/types/container/config.go b/components/cli/vendor/github.com/docker/docker/api/types/container/config.go -index c28f0b101e..4856626be4 100644 ---- a/components/cli/vendor/github.com/docker/docker/api/types/container/config.go -+++ b/components/cli/vendor/github.com/docker/docker/api/types/container/config.go -@@ -32,6 +32,9 @@ type HealthConfig struct { - // Retries is the number of consecutive failures needed to consider a container as unhealthy. - // Zero means inherit. - Retries int `json:",omitempty"` -+ -+ // Shut down a container if it becomes Unhealthy -+ ExitOnUnhealthy bool `json:",omitempty"` - } - - // Config contains the configuration data about a container. -diff --git a/components/engine/api/types/container/config.go b/components/engine/api/types/container/config.go -index c28f0b101e..4856626be4 100644 ---- a/components/engine/api/types/container/config.go -+++ b/components/engine/api/types/container/config.go -@@ -32,6 +32,9 @@ type HealthConfig struct { - // Retries is the number of consecutive failures needed to consider a container as unhealthy. - // Zero means inherit. - Retries int `json:",omitempty"` -+ -+ // Shut down a container if it becomes Unhealthy -+ ExitOnUnhealthy bool `json:",omitempty"` - } - - // Config contains the configuration data about a container. -diff --git a/components/engine/daemon/health.go b/components/engine/daemon/health.go -index ae0d7f8921..80bda66cb3 100644 ---- a/components/engine/daemon/health.go -+++ b/components/engine/daemon/health.go -@@ -241,6 +241,12 @@ func monitor(d *Daemon, c *container.Container, stop chan struct{}, probe probe) - // signal and we don't want dying probes to pile up). - <-results - } -+ if c.State.Health.Status() == types.Unhealthy && -+ c.Config.Healthcheck.ExitOnUnhealthy == true { -+ d.Kill(c) -+ logrus.Debugf("Shut down container %s because of unhealthy", c.ID) -+ return -+ } - } - } - } --- -2.17.1 - diff --git a/patch/0124-docker-Support-compress-when-saving-images.patch b/patch/0124-docker-Support-compress-when-saving-images.patch deleted file mode 100644 index c72713e..0000000 --- a/patch/0124-docker-Support-compress-when-saving-images.patch +++ /dev/null @@ -1,368 +0,0 @@ -From a671cf961c82749cd9025e3e9cce772650134a67 Mon Sep 17 00:00:00 2001 -From: Liu Hua -Date: Thu, 6 Jun 2019 01:13:08 -0400 -Subject: [PATCH] docker Support compress when saving images - -If add option `-c` when executing command `docker save`, -layer.tar in exported archive will be compressed with -algorithm gzip. Usage like this(we can use command `file` -to check format of the layer.tar): - -``` -$ docker save -c -o redis.tar redis -$ tar xvf redis.tar -09b9c5a923b810cc524ec5abf9dd65f796e37397005906b5d81c919bf63cb123/ -09b9c5a923b810cc524ec5abf9dd65f796e37397005906b5d81c919bf63cb123/VERSION -09b9c5a923b810cc524ec5abf9dd65f796e37397005906b5d81c919bf63cb123/json -09b9c5a923b810cc524ec5abf9dd65f796e37397005906b5d81c919bf63cb123/layer.tar -7613529f37fd6709b0d850a8ebecd13c069a9cb2bbf67babea0769c68172c5c9/ -7613529f37fd6709b0d850a8ebecd13c069a9cb2bbf67babea0769c68172c5c9/VERSION -7613529f37fd6709b0d850a8ebecd13c069a9cb2bbf67babea0769c68172c5c9/json -7613529f37fd6709b0d850a8ebecd13c069a9cb2bbf67babea0769c68172c5c9/layer.tar -846767a44c632a336d7204fb30e9215c84fb1ae1df81a557f78e0fc4d1842130/ -846767a44c632a336d7204fb30e9215c84fb1ae1df81a557f78e0fc4d1842130/VERSION -846767a44c632a336d7204fb30e9215c84fb1ae1df81a557f78e0fc4d1842130/json -846767a44c632a336d7204fb30e9215c84fb1ae1df81a557f78e0fc4d1842130/layer.tar -98ee6000320c9e7de792f9c17ac39233abd1881bb127f8227719740981742d7e/ -98ee6000320c9e7de792f9c17ac39233abd1881bb127f8227719740981742d7e/VERSION -98ee6000320c9e7de792f9c17ac39233abd1881bb127f8227719740981742d7e/json -98ee6000320c9e7de792f9c17ac39233abd1881bb127f8227719740981742d7e/layer.tar -a82ad3e3c9cd9fafcb310870d070fe293448e5a6d5681eafe54c88cb486038fc/ -a82ad3e3c9cd9fafcb310870d070fe293448e5a6d5681eafe54c88cb486038fc/VERSION -a82ad3e3c9cd9fafcb310870d070fe293448e5a6d5681eafe54c88cb486038fc/json -a82ad3e3c9cd9fafcb310870d070fe293448e5a6d5681eafe54c88cb486038fc/layer.tar -b047187f532984ce5e2b53a06c09f2621457939f87472673f35d15391ca58188/ -b047187f532984ce5e2b53a06c09f2621457939f87472673f35d15391ca58188/VERSION -b047187f532984ce5e2b53a06c09f2621457939f87472673f35d15391ca58188/json -b047187f532984ce5e2b53a06c09f2621457939f87472673f35d15391ca58188/layer.tar -d4f259423416b3c82b46e1caf01829ac3a99a211dfc691c9d862464768112e7f.json -manifest.json -repositories -$ file -b047187f532984ce5e2b53a06c09f2621457939f87472673f35d15391ca58188/layer.tar -b047187f532984ce5e2b53a06c09f2621457939f87472673f35d15391ca58188/layer.tar: -gzip compressed data -``` - -Change-Id: I9069b5346e4990e90c2f4724841dc3b4f6f5579f -Signed-off-by: Fengtu Wang -Signed-off-by: Liu Hua ---- - .../cli/cli/command/image/client_test.go | 2 +- - components/cli/cli/command/image/save.go | 8 +++++--- - .../docker/docker/client/image_save.go | 6 +++++- - .../docker/docker/client/interface.go | 2 +- - .../engine/api/server/router/image/backend.go | 2 +- - .../api/server/router/image/image_routes.go | 4 +++- - components/engine/client/image_save.go | 6 +++++- - components/engine/client/image_save_test.go | 4 ++-- - components/engine/client/interface.go | 2 +- - .../engine/daemon/images/image_exporter.go | 4 ++-- - components/engine/distribution/push.go | 2 +- - components/engine/distribution/push_v2.go | 2 +- - components/engine/image/image.go | 2 +- - components/engine/image/tarexport/save.go | 18 +++++++++++++++--- - .../plugin/authz/authz_plugin_test.go | 2 +- - .../engine/internal/test/daemon/daemon.go | 2 +- - 16 files changed, 46 insertions(+), 22 deletions(-) - -diff --git a/components/cli/cli/command/image/client_test.go b/components/cli/cli/command/image/client_test.go -index 50e46f4ec1..aa1bf13611 100644 ---- a/components/cli/cli/command/image/client_test.go -+++ b/components/cli/cli/command/image/client_test.go -@@ -37,7 +37,7 @@ func (cli *fakeClient) ImageTag(_ context.Context, image, ref string) error { - return nil - } - --func (cli *fakeClient) ImageSave(_ context.Context, images []string) (io.ReadCloser, error) { -+func (cli *fakeClient) ImageSave(_ context.Context, images []string, compress bool) (io.ReadCloser, error) { - if cli.imageSaveFunc != nil { - return cli.imageSaveFunc(images) - } -diff --git a/components/cli/cli/command/image/save.go b/components/cli/cli/command/image/save.go -index ef23ca1bb1..e1b4a21482 100644 ---- a/components/cli/cli/command/image/save.go -+++ b/components/cli/cli/command/image/save.go -@@ -13,8 +13,9 @@ import ( - ) - - type saveOptions struct { -- images []string -- output string -+ images []string -+ output string -+ compress bool - } - - // NewSaveCommand creates a new `docker save` command -@@ -34,6 +35,7 @@ func NewSaveCommand(dockerCli command.Cli) *cobra.Command { - flags := cmd.Flags() - - flags.StringVarP(&opts.output, "output", "o", "", "Write to a file, instead of STDOUT") -+ flags.BoolVarP(&opts.compress, "compress", "c", false, "Compress layers when saving images") - - return cmd - } -@@ -48,7 +50,7 @@ func RunSave(dockerCli command.Cli, opts saveOptions) error { - return errors.Wrap(err, "failed to save image") - } - -- responseBody, err := dockerCli.Client().ImageSave(context.Background(), opts.images) -+ responseBody, err := dockerCli.Client().ImageSave(context.Background(), opts.images, opts.compress) - if err != nil { - return err - } -diff --git a/components/cli/vendor/github.com/docker/docker/client/image_save.go b/components/cli/vendor/github.com/docker/docker/client/image_save.go -index d1314e4b22..2bbea0f8ff 100644 ---- a/components/cli/vendor/github.com/docker/docker/client/image_save.go -+++ b/components/cli/vendor/github.com/docker/docker/client/image_save.go -@@ -8,11 +8,15 @@ import ( - - // ImageSave retrieves one or more images from the docker host as an io.ReadCloser. - // It's up to the caller to store the images and close the stream. --func (cli *Client) ImageSave(ctx context.Context, imageIDs []string) (io.ReadCloser, error) { -+func (cli *Client) ImageSave(ctx context.Context, imageIDs []string, compress bool) (io.ReadCloser, error) { - query := url.Values{ - "names": imageIDs, - } - -+ if compress { -+ query.Set("compress", "1") -+ } -+ - resp, err := cli.get(ctx, "/images/get", query, nil) - if err != nil { - return nil, err -diff --git a/components/cli/vendor/github.com/docker/docker/client/interface.go b/components/cli/vendor/github.com/docker/docker/client/interface.go -index b2d5d7bb72..e68f9f6264 100644 ---- a/components/cli/vendor/github.com/docker/docker/client/interface.go -+++ b/components/cli/vendor/github.com/docker/docker/client/interface.go -@@ -98,7 +98,7 @@ type ImageAPIClient interface { - ImagePush(ctx context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error) - ImageRemove(ctx context.Context, image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) - ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) -- ImageSave(ctx context.Context, images []string) (io.ReadCloser, error) -+ ImageSave(ctx context.Context, images []string, compress bool) (io.ReadCloser, error) - ImageTag(ctx context.Context, image, ref string) error - ImagesPrune(ctx context.Context, pruneFilter filters.Args) (types.ImagesPruneReport, error) - } -diff --git a/components/engine/api/server/router/image/backend.go b/components/engine/api/server/router/image/backend.go -index 5837f9a9bc..84509d301a 100644 ---- a/components/engine/api/server/router/image/backend.go -+++ b/components/engine/api/server/router/image/backend.go -@@ -31,7 +31,7 @@ type imageBackend interface { - type importExportBackend interface { - LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error - ImportImage(src string, repository, platform string, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error -- ExportImage(names []string, outStream io.Writer) error -+ ExportImage(names []string, compress bool, outStream io.Writer) error - } - - type registryBackend interface { -diff --git a/components/engine/api/server/router/image/image_routes.go b/components/engine/api/server/router/image/image_routes.go -index 85707c06d2..b7bb340e9a 100644 ---- a/components/engine/api/server/router/image/image_routes.go -+++ b/components/engine/api/server/router/image/image_routes.go -@@ -159,7 +159,9 @@ func (s *imageRouter) getImagesGet(ctx context.Context, w http.ResponseWriter, r - names = r.Form["names"] - } - -- if err := s.backend.ExportImage(names, output); err != nil { -+ compress := httputils.BoolValueOrDefault(r, "compress", false) -+ -+ if err := s.backend.ExportImage(names, compress, output); err != nil { - if !output.Flushed() { - return err - } -diff --git a/components/engine/client/image_save.go b/components/engine/client/image_save.go -index d1314e4b22..2bbea0f8ff 100644 ---- a/components/engine/client/image_save.go -+++ b/components/engine/client/image_save.go -@@ -8,11 +8,15 @@ import ( - - // ImageSave retrieves one or more images from the docker host as an io.ReadCloser. - // It's up to the caller to store the images and close the stream. --func (cli *Client) ImageSave(ctx context.Context, imageIDs []string) (io.ReadCloser, error) { -+func (cli *Client) ImageSave(ctx context.Context, imageIDs []string, compress bool) (io.ReadCloser, error) { - query := url.Values{ - "names": imageIDs, - } - -+ if compress { -+ query.Set("compress", "1") -+ } -+ - resp, err := cli.get(ctx, "/images/get", query, nil) - if err != nil { - return nil, err -diff --git a/components/engine/client/image_save_test.go b/components/engine/client/image_save_test.go -index a40055e583..7325da0c80 100644 ---- a/components/engine/client/image_save_test.go -+++ b/components/engine/client/image_save_test.go -@@ -15,7 +15,7 @@ func TestImageSaveError(t *testing.T) { - client := &Client{ - client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), - } -- _, err := client.ImageSave(context.Background(), []string{"nothing"}) -+ _, err := client.ImageSave(context.Background(), []string{"nothing"}, false) - if err == nil || err.Error() != "Error response from daemon: Server error" { - t.Fatalf("expected a Server error, got %v", err) - } -@@ -41,7 +41,7 @@ func TestImageSave(t *testing.T) { - }, nil - }), - } -- saveResponse, err := client.ImageSave(context.Background(), []string{"image_id1", "image_id2"}) -+ saveResponse, err := client.ImageSave(context.Background(), []string{"image_id1", "image_id2"}, false) - if err != nil { - t.Fatal(err) - } -diff --git a/components/engine/client/interface.go b/components/engine/client/interface.go -index d190f8e58d..5a7b9eb5b8 100644 ---- a/components/engine/client/interface.go -+++ b/components/engine/client/interface.go -@@ -98,7 +98,7 @@ type ImageAPIClient interface { - ImagePush(ctx context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error) - ImageRemove(ctx context.Context, image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) - ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) -- ImageSave(ctx context.Context, images []string) (io.ReadCloser, error) -+ ImageSave(ctx context.Context, images []string, compress bool) (io.ReadCloser, error) - ImageTag(ctx context.Context, image, ref string) error - ImagesPrune(ctx context.Context, pruneFilter filters.Args) (types.ImagesPruneReport, error) - } -diff --git a/components/engine/daemon/images/image_exporter.go b/components/engine/daemon/images/image_exporter.go -index 58105dcb71..dbe5811f30 100644 ---- a/components/engine/daemon/images/image_exporter.go -+++ b/components/engine/daemon/images/image_exporter.go -@@ -11,9 +11,9 @@ import ( - // stream. All images with the given tag and all versions containing - // the same tag are exported. names is the set of tags to export, and - // outStream is the writer which the images are written to. --func (i *ImageService) ExportImage(names []string, outStream io.Writer) error { -+func (i *ImageService) ExportImage(names []string, compress bool, outStream io.Writer) error { - imageExporter := tarexport.NewTarExporter(i.imageStore, i.layerStores, i.referenceStore, i) -- return imageExporter.Save(names, outStream) -+ return imageExporter.Save(names, compress, outStream) - } - - // LoadImage uploads a set of images into the repository. This is the -diff --git a/components/engine/distribution/push.go b/components/engine/distribution/push.go -index eb3bc55974..ca49f22926 100644 ---- a/components/engine/distribution/push.go -+++ b/components/engine/distribution/push.go -@@ -158,7 +158,7 @@ func Push(ctx context.Context, ref reference.Named, imagePushConfig *ImagePushCo - // is finished. This allows the caller to make sure the goroutine finishes - // before it releases any resources connected with the reader that was - // passed in. --func compress(in io.Reader) (io.ReadCloser, chan struct{}) { -+func Compress(in io.Reader) (io.ReadCloser, chan struct{}) { - compressionDone := make(chan struct{}) - - pipeReader, pipeWriter := io.Pipe() -diff --git a/components/engine/distribution/push_v2.go b/components/engine/distribution/push_v2.go -index 9dc3e7a2a6..f5922d65bf 100644 ---- a/components/engine/distribution/push_v2.go -+++ b/components/engine/distribution/push_v2.go -@@ -447,7 +447,7 @@ func (pd *v2PushDescriptor) uploadUsingSession( - - switch m := pd.layer.MediaType(); m { - case schema2.MediaTypeUncompressedLayer: -- compressedReader, compressionDone := compress(reader) -+ compressedReader, compressionDone := Compress(reader) - defer func(closer io.Closer) { - closer.Close() - <-compressionDone -diff --git a/components/engine/image/image.go b/components/engine/image/image.go -index 7e0646f072..bb6046b5ec 100644 ---- a/components/engine/image/image.go -+++ b/components/engine/image/image.go -@@ -212,7 +212,7 @@ func NewHistory(author, comment, createdBy string, isEmptyLayer bool) History { - type Exporter interface { - Load(io.ReadCloser, io.Writer, bool) error - // TODO: Load(net.Context, io.ReadCloser, <- chan StatusMessage) error -- Save([]string, io.Writer) error -+ Save([]string, bool, io.Writer) error - } - - // NewFromJSON creates an Image configuration from json. -diff --git a/components/engine/image/tarexport/save.go b/components/engine/image/tarexport/save.go -index 4e734b3503..0683f1704f 100644 ---- a/components/engine/image/tarexport/save.go -+++ b/components/engine/image/tarexport/save.go -@@ -12,6 +12,7 @@ import ( - "time" - - "github.com/docker/distribution" -+ dd "github.com/docker/docker/distribution" - "github.com/docker/distribution/reference" - "github.com/docker/docker/image" - "github.com/docker/docker/image/v1" -@@ -35,9 +36,10 @@ type saveSession struct { - images map[image.ID]*imageDescriptor - savedLayers map[string]struct{} - diffIDPaths map[layer.DiffID]string // cache every diffID blob to avoid duplicates -+ compress bool - } - --func (l *tarexporter) Save(names []string, outStream io.Writer) error { -+func (l *tarexporter) Save(names []string, compress bool, outStream io.Writer) error { - images, err := l.parseNames(names) - if err != nil { - return err -@@ -45,7 +47,7 @@ func (l *tarexporter) Save(names []string, outStream io.Writer) error { - - // Release all the image top layer references - defer l.releaseLayerReferences(images) -- return (&saveSession{tarexporter: l, images: images}).save(outStream) -+ return (&saveSession{tarexporter: l, images: images, compress: compress}).save(outStream) - } - - // parseNames will parse the image names to a map which contains image.ID to *imageDescriptor. -@@ -408,7 +410,17 @@ func (s *saveSession) saveLayer(id layer.ChainID, legacyImg image.V1Image, creat - } - defer arch.Close() - -- if _, err := io.Copy(tarFile, arch); err != nil { -+ reader := arch -+ var compressionDone chan struct{} -+ if s.compress { -+ reader, compressionDone = dd.Compress(arch) -+ defer func(closer io.Closer) { -+ closer.Close() -+ <-compressionDone -+ }(reader) -+ } -+ -+ if _, err := io.Copy(tarFile, reader); err != nil { - return distribution.Descriptor{}, err - } - -diff --git a/components/engine/integration/plugin/authz/authz_plugin_test.go b/components/engine/integration/plugin/authz/authz_plugin_test.go -index 105affc1af..c740fc1dbd 100644 ---- a/components/engine/integration/plugin/authz/authz_plugin_test.go -+++ b/components/engine/integration/plugin/authz/authz_plugin_test.go -@@ -435,7 +435,7 @@ func TestAuthzPluginEnsureContainerCopyToFrom(t *testing.T) { - - func imageSave(client client.APIClient, path, image string) error { - ctx := context.Background() -- responseReader, err := client.ImageSave(ctx, []string{image}) -+ responseReader, err := client.ImageSave(ctx, []string{image}, false) - if err != nil { - return err - } -diff --git a/components/engine/internal/test/daemon/daemon.go b/components/engine/internal/test/daemon/daemon.go -index 4f56dff9bb..f16a43de45 100644 ---- a/components/engine/internal/test/daemon/daemon.go -+++ b/components/engine/internal/test/daemon/daemon.go -@@ -557,7 +557,7 @@ func (d *Daemon) LoadBusybox(t assert.TestingT) { - defer clientHost.Close() - - ctx := context.Background() -- reader, err := clientHost.ImageSave(ctx, []string{"busybox:latest"}) -+ reader, err := clientHost.ImageSave(ctx, []string{"busybox:latest"}, false) - assert.NilError(t, err, "failed to download busybox") - defer reader.Close() - --- -2.17.1 - diff --git a/patch/0125-docker-add-hugetlb-limit-option-to-docker.patch b/patch/0125-docker-add-hugetlb-limit-option-to-docker.patch deleted file mode 100644 index d613061..0000000 --- a/patch/0125-docker-add-hugetlb-limit-option-to-docker.patch +++ /dev/null @@ -1,642 +0,0 @@ -From 74bad908a52fd2713c72c9f42f2b053369ec53d2 Mon Sep 17 00:00:00 2001 -From: zhaolongquan1 -Date: Wed, 12 Jun 2019 12:37:08 -0400 -Subject: [PATCH] docker: add hugetlb limit option to docker - -reason:add hugetlb limit option to docker - -Change-Id: I418c65fd050d3740da6997589df45b08355fed80 -Signed-off-by: zhaolongquan1 ---- - components/cli/cli/command/container/opts.go | 5 + - components/cli/cli/command/system/info.go | 1 + - components/cli/contrib/completion/bash/docker | 1 + - components/cli/opts/hugetlb.go | 109 +++++++++++++ - .../docker/api/types/container/host_config.go | 8 + - .../github.com/docker/docker/api/types/types.go | 1 + - .../engine/api/types/container/host_config.go | 8 + - components/engine/api/types/types.go | 1 + - components/engine/daemon/daemon_unix.go | 66 ++++++++ - components/engine/daemon/info.go | 1 + - components/engine/daemon/oci_linux.go | 2 + - components/engine/pkg/sysinfo/sysinfo.go | 6 + - components/engine/pkg/sysinfo/sysinfo_linux.go | 30 ++++ - components/engine/pkg/sysinfo/utils_linux.go | 169 +++++++++++++++++++++ - 14 files changed, 408 insertions(+) - create mode 100644 components/cli/opts/hugetlb.go - create mode 100644 components/engine/pkg/sysinfo/utils_linux.go - -diff --git a/components/cli/cli/command/container/opts.go b/components/cli/cli/command/container/opts.go -index 00da8fc..d729a3c 100644 ---- a/components/cli/cli/command/container/opts.go -+++ b/components/cli/cli/command/container/opts.go -@@ -66,6 +66,7 @@ type containerOptions struct { - storageOpt opts.ListOpts - labelsFile opts.ListOpts - loggingOpts opts.ListOpts -+ hugetlb opts.HugetlbOpt - privileged bool - pidMode string - utsMode string -@@ -166,6 +167,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { - ulimits: opts.NewUlimitOpt(nil), - volumes: opts.NewListOpts(nil), - volumesFrom: opts.NewListOpts(nil), -+ hugetlb: opts.NewHugetlbOpt(opts.ValidateHugetlb), - } - - // General purpose flags -@@ -295,6 +297,8 @@ func addFlags(flags *pflag.FlagSet) *containerOptions { - - flags.BoolVar(&copts.init, "init", false, "Run an init inside the container that forwards signals and reaps processes") - flags.SetAnnotation("init", "version", []string{"1.25"}) -+ -+ flags.Var(&copts.hugetlb, "hugetlb-limit", "Huge page limit (format: [size:], e.g. --hugetlb-limit 2MB:32MB)") - return copts - } - -@@ -538,6 +542,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err - - resources := container.Resources{ - CgroupParent: copts.cgroupParent, -+ Hugetlbs: copts.hugetlb.GetAll(), - Memory: copts.memory.Value(), - MemoryReservation: copts.memoryReservation.Value(), - MemorySwap: copts.memorySwap.Value(), -diff --git a/components/cli/cli/command/system/info.go b/components/cli/cli/command/system/info.go -index 17ccc14..7399d10 100644 ---- a/components/cli/cli/command/system/info.go -+++ b/components/cli/cli/command/system/info.go -@@ -74,6 +74,7 @@ func prettyPrintInfo(dockerCli command.Cli, info types.Info) error { - } - fprintlnNonEmpty(dockerCli.Out(), "Logging Driver:", info.LoggingDriver) - fprintlnNonEmpty(dockerCli.Out(), "Cgroup Driver:", info.CgroupDriver) -+ fprintlnNonEmpty(dockerCli.Out(), "Hugetlb Pagesize:", info.HugetlbPageSize) - - fmt.Fprintln(dockerCli.Out(), "Plugins:") - fmt.Fprintln(dockerCli.Out(), " Volume:", strings.Join(info.Plugins.Volume, " ")) -diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker -index 64f7fe0..330804d 100644 ---- a/components/cli/contrib/completion/bash/docker -+++ b/components/cli/contrib/completion/bash/docker -@@ -1792,6 +1792,7 @@ _docker_container_run_and_create() { - --files-limit - --group-add - --hook-spec -+ --hugetlb-limit - --health-cmd - --health-interval - --health-retries -diff --git a/components/cli/opts/hugetlb.go b/components/cli/opts/hugetlb.go -new file mode 100644 -index 0000000..48cfeff ---- /dev/null -+++ b/components/cli/opts/hugetlb.go -@@ -0,0 +1,109 @@ -+package opts -+ -+import ( -+ "fmt" -+ "strings" -+ -+ "github.com/docker/docker/api/types/container" -+ "github.com/docker/go-units" -+) -+ -+// ValidatorHugetlbType defines a validator function that returns a validated struct and/or an error. -+type ValidatorHugetlbType func(val string) (container.Hugetlb, error) -+ -+// ValidateHugetlb validates that the specified string has a valid hugetlb format. -+func ValidateHugetlb(htlb string) (container.Hugetlb, error) { -+ var size, limit string -+ var hugetlb container.Hugetlb -+ -+ ss := strings.Split(htlb, ":") -+ if len(ss) == 1 { -+ size = "" -+ limit = ss[0] -+ } else if len(ss) == 2 { -+ if ss[0] == "" { -+ size = "" -+ } else { -+ size = formatHugepageSize(ss[0]) -+ } -+ limit = ss[1] -+ } else { -+ return hugetlb, fmt.Errorf("Invalid arguments for hugetlb-limit, too many colons") -+ } -+ -+ ilimit, err := units.RAMInBytes(limit) -+ if err != nil { -+ return hugetlb, fmt.Errorf("Invalid hugetlb limit:%s", limit) -+ } -+ ulimit := uint64(ilimit) -+ hugetlb = container.Hugetlb{ -+ PageSize: size, -+ Limit: ulimit, -+ } -+ return hugetlb, nil -+} -+ -+// HugetlbOpt defines a map of Hugetlbs -+type HugetlbOpt struct { -+ values []container.Hugetlb -+ validator ValidatorHugetlbType -+} -+ -+// NewHugetlbOpt creates a new HugetlbOpt -+func NewHugetlbOpt(validator ValidatorHugetlbType) HugetlbOpt { -+ values := []container.Hugetlb{} -+ return HugetlbOpt{ -+ values: values, -+ validator: validator, -+ } -+} -+ -+// Set validates a Hugetlb and sets its name as a key in HugetlbOpt -+func (opt *HugetlbOpt) Set(val string) error { -+ var value container.Hugetlb -+ if opt.validator != nil { -+ v, err := opt.validator(val) -+ if err != nil { -+ return err -+ } -+ value = v -+ } -+ (opt.values) = append((opt.values), value) -+ return nil -+} -+ -+// String returns HugetlbOpt values as a string. -+func (opt *HugetlbOpt) String() string { -+ var out []string -+ for _, v := range opt.values { -+ out = append(out, fmt.Sprintf("%v", v)) -+ } -+ -+ return fmt.Sprintf("%v", out) -+} -+ -+// GetList returns a slice of pointers to Hugetlbs. -+func (opt *HugetlbOpt) GetAll() []container.Hugetlb { -+ var hugetlbs []container.Hugetlb -+ for _, v := range opt.values { -+ hugetlbs = append(hugetlbs, v) -+ } -+ -+ return hugetlbs -+} -+ -+// Type returns the option type -+func (opt *HugetlbOpt) Type() string { -+ return "hugetlb" -+} -+ -+func formatHugepageSize(s string) string { -+ // make sure size get all 'b/k/m/g' replaced with "B/K/M/G" -+ s = strings.ToUpper(s) -+ // make sure size hase suffix "B" -+ if !strings.HasSuffix(s, "B") { -+ s = s + "B" -+ } -+ -+ return s -+} -diff --git a/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go b/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go -index 701cae5..6989b2b 100644 ---- a/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go -+++ b/components/cli/vendor/github.com/docker/docker/api/types/container/host_config.go -@@ -342,6 +342,14 @@ type Resources struct { - CPUPercent int64 `json:"CpuPercent"` // CPU percent - IOMaximumIOps uint64 // Maximum IOps for the container system drive - IOMaximumBandwidth uint64 // Maximum IO in bytes per second for the container system drive -+ -+ // Hugetlb setting -+ Hugetlbs []Hugetlb -+} -+ -+type Hugetlb struct { -+ PageSize string -+ Limit uint64 - } - - // UpdateConfig holds the mutable attributes of a Container. -diff --git a/components/cli/vendor/github.com/docker/docker/api/types/types.go b/components/cli/vendor/github.com/docker/docker/api/types/types.go -index 56f556c..cfcfd4a 100644 ---- a/components/cli/vendor/github.com/docker/docker/api/types/types.go -+++ b/components/cli/vendor/github.com/docker/docker/api/types/types.go -@@ -173,6 +173,7 @@ type Info struct { - SystemTime string - LoggingDriver string - CgroupDriver string -+ HugetlbPageSize string - NEventsListener int - KernelVersion string - OperatingSystem string -diff --git a/components/engine/api/types/container/host_config.go b/components/engine/api/types/container/host_config.go -index 701cae5..6989b2b 100644 ---- a/components/engine/api/types/container/host_config.go -+++ b/components/engine/api/types/container/host_config.go -@@ -342,6 +342,14 @@ type Resources struct { - CPUPercent int64 `json:"CpuPercent"` // CPU percent - IOMaximumIOps uint64 // Maximum IOps for the container system drive - IOMaximumBandwidth uint64 // Maximum IO in bytes per second for the container system drive -+ -+ // Hugetlb setting -+ Hugetlbs []Hugetlb -+} -+ -+type Hugetlb struct { -+ PageSize string -+ Limit uint64 - } - - // UpdateConfig holds the mutable attributes of a Container. -diff --git a/components/engine/api/types/types.go b/components/engine/api/types/types.go -index 78e97da..55955f2 100644 ---- a/components/engine/api/types/types.go -+++ b/components/engine/api/types/types.go -@@ -174,6 +174,7 @@ type Info struct { - SystemTime string - LoggingDriver string - CgroupDriver string -+ HugetlbPageSize string - NEventsListener int - KernelVersion string - OperatingSystem string -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index 9abc9a3..5a59b32 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -187,6 +187,21 @@ func getBlkioWeightDevices(config containertypes.Resources) ([]specs.LinuxWeight - return blkioWeightDevices, nil - } - -+func getHugetlbResources(config containertypes.Resources) []specs.LinuxHugepageLimit { -+ var hpLimits []specs.LinuxHugepageLimit -+ -+ for _, hpl := range config.Hugetlbs { -+ size := hpl.PageSize -+ limit := uint64(hpl.Limit) -+ hpLimits = append(hpLimits, specs.LinuxHugepageLimit{ -+ Pagesize: size, -+ Limit: limit, -+ }) -+ } -+ -+ return hpLimits -+} -+ - func (daemon *Daemon) parseSecurityOpt(container *container.Container, hostConfig *containertypes.HostConfig) error { - container.NoNewPrivileges = daemon.configStore.NoNewPrivileges - return parseSecurityOpt(container, hostConfig) -@@ -553,9 +568,51 @@ func (daemon *Daemon) verifyContainerResources(hostConfig *containertypes.HostCo - resources.BlkioDeviceWriteIOps = []*pblkiodev.ThrottleDevice{} - } - -+ // hugetlb size checks -+ if len(resources.Hugetlbs) > 0 && !sysInfo.HugetlbLimit { -+ warnings = append(warnings, "Your kernel does not support hugetlb limit.") -+ logrus.Warnf("Your kernel does not support hugetlb limit. --hugetlb-limit discarded.") -+ resources.Hugetlbs = []containertypes.Hugetlb{} -+ } -+ newHugetlbs, warning, err := validateHugetlbs(resources.Hugetlbs) -+ warnings = append(warnings, warning...) -+ if err != nil { -+ return warnings, err -+ } -+ resources.Hugetlbs = newHugetlbs -+ - return warnings, nil - } - -+func validateHugetlbs(hgtlbs []containertypes.Hugetlb) ([]containertypes.Hugetlb, []string, error) { -+ warnings := []string{} -+ htbMap := make(map[string]uint64) -+ -+ for _, hpl := range hgtlbs { -+ size, warning, err := sysinfo.ValidateHugetlb(hpl.PageSize, hpl.Limit) -+ warnings = append(warnings, warning...) -+ if err != nil { -+ return nil, warnings, err -+ } -+ -+ if l, ok := htbMap[size]; ok { -+ warnings = append(warnings, fmt.Sprintf("hugetlb-limit setting of %s is repeated, former setting %d will be replaced with %d", size, l, hpl.Limit)) -+ } -+ htbMap[size] = hpl.Limit -+ } -+ -+ newHgtlbs := []containertypes.Hugetlb{} -+ for k, v := range htbMap { -+ hugetlb := containertypes.Hugetlb{ -+ PageSize: k, -+ Limit: v, -+ } -+ newHgtlbs = append(newHgtlbs, hugetlb) -+ } -+ -+ return newHgtlbs, warnings, nil -+} -+ - func (daemon *Daemon) getCgroupDriver() string { - cgroupDriver := cgroupFsDriver - -@@ -565,6 +622,15 @@ func (daemon *Daemon) getCgroupDriver() string { - return cgroupDriver - } - -+func (daemon *Daemon) getHugetlbPageSize() string { -+ size, err := sysinfo.GetHugepageSize() -+ if err != nil { -+ logrus.Errorf("Failed to get default hugetlb pagesize: %v", err) -+ return "" -+ } -+ return size -+} -+ - // getCD gets the raw value of the native.cgroupdriver option, if set. - func getCD(config *config.Config) string { - for _, option := range config.ExecOptions { -diff --git a/components/engine/daemon/info.go b/components/engine/daemon/info.go -index 4acad11..2ecff72 100644 ---- a/components/engine/daemon/info.go -+++ b/components/engine/daemon/info.go -@@ -47,6 +47,7 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) { - SystemTime: time.Now().Format(time.RFC3339Nano), - LoggingDriver: daemon.defaultLogConfig.Type, - CgroupDriver: daemon.getCgroupDriver(), -+ HugetlbPageSize: daemon.getHugetlbPageSize(), - NEventsListener: daemon.EventsService.SubscribersCount(), - KernelVersion: kernelVersion(), - OperatingSystem: operatingSystem(), -diff --git a/components/engine/daemon/oci_linux.go b/components/engine/daemon/oci_linux.go -index f5270bd..6d3bc16 100644 ---- a/components/engine/daemon/oci_linux.go -+++ b/components/engine/daemon/oci_linux.go -@@ -49,6 +49,7 @@ func setResources(s *specs.Spec, r containertypes.Resources) error { - return err - } - -+ hpRes := getHugetlbResources(r) - memoryRes := getMemoryResources(r) - cpuRes, err := getCPUResources(r) - if err != nil { -@@ -73,6 +74,7 @@ func setResources(s *specs.Spec, r containertypes.Resources) error { - Files: &specs.Files{ - Limit: &r.FilesLimit, - }, -+ HugepageLimits: hpRes, - } - - if s.Linux.Resources != nil && len(s.Linux.Resources.Devices) > 0 { -diff --git a/components/engine/pkg/sysinfo/sysinfo.go b/components/engine/pkg/sysinfo/sysinfo.go -index 7ea1be5..139ad61 100644 ---- a/components/engine/pkg/sysinfo/sysinfo.go -+++ b/components/engine/pkg/sysinfo/sysinfo.go -@@ -17,6 +17,7 @@ type SysInfo struct { - Seccomp bool - - cgroupMemInfo -+ cgroupHugetlbInfo - cgroupCPUInfo - cgroupBlkioInfo - cgroupCpusetInfo -@@ -56,6 +57,11 @@ type cgroupMemInfo struct { - KernelMemory bool - } - -+type cgroupHugetlbInfo struct { -+ // Whether hugetlb limit is supported or not -+ HugetlbLimit bool -+} -+ - type cgroupCPUInfo struct { - // Whether CPU shares is supported or not - CPUShares bool -diff --git a/components/engine/pkg/sysinfo/sysinfo_linux.go b/components/engine/pkg/sysinfo/sysinfo_linux.go -index c0bf280..b4473ee 100644 ---- a/components/engine/pkg/sysinfo/sysinfo_linux.go -+++ b/components/engine/pkg/sysinfo/sysinfo_linux.go -@@ -36,6 +36,7 @@ func New(quiet bool) *SysInfo { - logrus.Warnf("Failed to parse cgroup information: %v", err) - } else { - sysInfo.cgroupMemInfo = checkCgroupMem(cgMounts, quiet) -+ sysInfo.cgroupHugetlbInfo = checkCgroupHugetlb(cgMounts, quiet) - sysInfo.cgroupCPUInfo = checkCgroupCPU(cgMounts, quiet) - sysInfo.cgroupBlkioInfo = checkCgroupBlkioInfo(cgMounts, quiet) - sysInfo.cgroupCpusetInfo = checkCgroupCpusetInfo(cgMounts, quiet) -@@ -66,6 +67,35 @@ func New(quiet bool) *SysInfo { - return sysInfo - } - -+// checkCgroupHugetlb reads the hugetlb information from the hugetlb cgroup mount point. -+func checkCgroupHugetlb(cgMounts map[string]string, quiet bool) cgroupHugetlbInfo { -+ var ( -+ dSize string -+ err error -+ c cgroupHugetlbInfo -+ ) -+ mountPoint, ok := cgMounts["hugetlb"] -+ if !ok { -+ if !quiet { -+ logrus.Warnf("Your kernel does not support cgroup hugetlb limit") -+ } -+ return c -+ } -+ dSize, err = GetDefaultHugepageSize() -+ if err != nil { -+ logrus.Warnf("Your kernel does not support cgroup hugetlb limit") -+ return c -+ } -+ -+ hugetlbLimit := cgroupEnabled(mountPoint, fmt.Sprintf("hugetlb.%s.limit_in_bytes", dSize)) -+ if !quiet && !hugetlbLimit { -+ logrus.Warn("Your kernel does not support hugetlb limit.") -+ } -+ -+ c.HugetlbLimit = hugetlbLimit -+ return c -+} -+ - // checkCgroupMem reads the memory information from the memory cgroup mount point. - func checkCgroupMem(cgMounts map[string]string, quiet bool) cgroupMemInfo { - mountPoint, ok := cgMounts["memory"] -diff --git a/components/engine/pkg/sysinfo/utils_linux.go b/components/engine/pkg/sysinfo/utils_linux.go -new file mode 100644 -index 0000000..905d0b7 ---- /dev/null -+++ b/components/engine/pkg/sysinfo/utils_linux.go -@@ -0,0 +1,169 @@ -+// +build linux -+ -+package sysinfo -+ -+import ( -+ "bufio" -+ "fmt" -+ "os" -+ "strings" -+ -+ "github.com/docker/go-units" -+ "github.com/opencontainers/runc/libcontainer/cgroups" -+) -+ -+// GetHugepageSize returns system supported hugepage sizes -+func GetHugepageSize() (string, error) { -+ hps, err := getHugepageSizes() -+ if err != nil { -+ return "", err -+ } -+ -+ dhp, err := GetDefaultHugepageSize() -+ if err != nil { -+ return "", err -+ } -+ -+ hpsString := strings.Join(hps, ", ") -+ if len(hps) > 1 { -+ hpsString += fmt.Sprintf(" (default is %s)", dhp) -+ } -+ return hpsString, nil -+} -+ -+// ValidateHugetlb check whether hugetlb pagesize and limit legal -+func ValidateHugetlb(pageSize string, limit uint64) (string, []string, error) { -+ var err error -+ warnings := []string{} -+ if pageSize != "" { -+ sizeInt, _ := units.RAMInBytes(pageSize) -+ pageSize = humanSize(sizeInt) -+ if err := isHugepageSizeValid(pageSize); err != nil { -+ return "", warnings, err -+ } -+ } else { -+ pageSize, err = GetDefaultHugepageSize() -+ if err != nil { -+ return "", warnings, fmt.Errorf("Failed to get system hugepage size") -+ } -+ } -+ -+ warn, err := isHugeLimitValid(pageSize, limit) -+ warnings = append(warnings, warn...) -+ if err != nil { -+ return "", warnings, err -+ } -+ -+ return pageSize, warnings, nil -+} -+ -+// isHugeLimitValid check whether input hugetlb limit legal -+// it will check whether the limit size is times of size -+func isHugeLimitValid(size string, limit uint64) ([]string, error) { -+ warnings := []string{} -+ sizeInt, err := units.RAMInBytes(size) -+ if err != nil || sizeInt < 0 { -+ return warnings, fmt.Errorf("Invalid hugepage size:%s -- %s", size, err) -+ } -+ sizeUint := uint64(sizeInt) -+ -+ if limit%sizeUint != 0 { -+ warnings = append(warnings, "HugeTlb limit should be times of hugepage size. "+ -+ "cgroup will down round to the nearest multiple") -+ } -+ -+ return warnings, nil -+} -+ -+// isHugepageSizeValid check whether input size legal -+// it will compare size with all system supported hugepage size -+func isHugepageSizeValid(size string) error { -+ hps, err := getHugepageSizes() -+ if err != nil { -+ return err -+ } -+ -+ for _, hp := range hps { -+ if size == hp { -+ return nil -+ } -+ } -+ return fmt.Errorf("Invalid hugepage size:%s, shoud be one of %v", size, hps) -+} -+ -+func humanSize(i int64) string { -+ // hugetlb may not surpass GB -+ uf := []string{"B", "KB", "MB", "GB"} -+ ui := 0 -+ for { -+ if i < 1024 || ui >= 3 { -+ break -+ } -+ i = int64(i / 1024) -+ ui = ui + 1 -+ } -+ -+ return fmt.Sprintf("%d%s", i, uf[ui]) -+} -+ -+func getHugepageSizes() ([]string, error) { -+ var hps []string -+ -+ hgtlbMp, err := cgroups.FindCgroupMountpoint("hugetlb") -+ if err != nil { -+ return nil, fmt.Errorf("Hugetlb cgroup not supported") -+ } -+ -+ f, err := os.Open(hgtlbMp) -+ if err != nil { -+ return nil, fmt.Errorf("Failed to open hugetlb cgroup directory") -+ } -+ defer f.Close() -+ // -1 here means to read all the fileInfo from the directory, could be any negative number -+ fi, err := f.Readdir(-1) -+ if err != nil { -+ return nil, fmt.Errorf("Failed to read hugetlb cgroup directory") -+ } -+ -+ for _, finfo := range fi { -+ if strings.Contains(finfo.Name(), "limit_in_bytes") { -+ sres := strings.SplitN(finfo.Name(), ".", 3) -+ if len(sres) != 3 { -+ continue -+ } -+ hps = append(hps, sres[1]) -+ } -+ } -+ -+ if len(hps) == 0 { -+ return nil, fmt.Errorf("Hugetlb pagesize not found in cgroup") -+ } -+ -+ return hps, nil -+} -+ -+// GetDefaultHugepageSize returns system default hugepage size -+func GetDefaultHugepageSize() (string, error) { -+ f, err := os.Open("/proc/meminfo") -+ if err != nil { -+ return "", fmt.Errorf("Failed to get hugepage size, cannot open /proc/meminfo") -+ } -+ defer f.Close() -+ -+ s := bufio.NewScanner(f) -+ for s.Scan() { -+ if strings.Contains(s.Text(), "Hugepagesize") { -+ sres := strings.SplitN(s.Text(), ":", 2) -+ if len(sres) != 2 { -+ return "", fmt.Errorf("Failed to get hugepage size, weird /proc/meminfo format") -+ } -+ -+ // return strings.TrimSpace(sres[1]), nil -+ size := strings.Replace(sres[1], " ", "", -1) -+ // transform 2048k to 2M -+ sizeInt, _ := units.RAMInBytes(size) -+ return humanSize(sizeInt), nil -+ } -+ } -+ return "", fmt.Errorf("Failed to get hugepage size") -+} --- -1.8.3.1 - diff --git a/patch/0126-docker-pass-root-to-chroot-to-for-chroot-ta.patch b/patch/0126-docker-pass-root-to-chroot-to-for-chroot-ta.patch deleted file mode 100644 index 9520bad..0000000 --- a/patch/0126-docker-pass-root-to-chroot-to-for-chroot-ta.patch +++ /dev/null @@ -1,551 +0,0 @@ -From 4a5b04a22ee93b76787c5cf5070b49f6337dd1fe Mon Sep 17 00:00:00 2001 -From: wujibin -Date: Tue, 11 Jun 2019 16:17:02 +0800 -Subject: [PATCH] docker: pass root to chroot to for chroot tar/untar - -This is useful for preventing CVE-2018-15664 where a malicious container process can take -advantage of a race on symlink resolution/sanitization -Vulnerability CVE-2018-15664 link: -https://tools.cisco.com/security/center/viewAlert.x?alertId=60251 -Pass root to chroot to for chroot Untar: -https://github.com/docker/docker-ce/commit/23dc194c079c60a00d079efc73dbb590bc220a6b -Add chroot for tar packing operations: -https://github.com/docker/docker-ce/commit/7432dfa7495303bf7d0246ca02de57d2995f1f78 - -Signed-off-by: wujibin ---- - components/engine/daemon/archive.go | 15 +- - components/engine/daemon/export.go | 2 +- - .../engine/pkg/chrootarchive/archive.go | 32 +++- - .../engine/pkg/chrootarchive/archive_unix.go | 130 ++++++++++++- - .../pkg/chrootarchive/archive_unix_test.go | 171 ++++++++++++++++++ - .../pkg/chrootarchive/archive_windows.go | 9 +- - .../engine/pkg/chrootarchive/init_unix.go | 1 + - 7 files changed, 342 insertions(+), 18 deletions(-) - create mode 100644 components/engine/pkg/chrootarchive/archive_unix_test.go - -diff --git a/components/engine/daemon/archive.go b/components/engine/daemon/archive.go -index f1b715d9ae..d5d0412034 100644 ---- a/components/engine/daemon/archive.go -+++ b/components/engine/daemon/archive.go -@@ -32,18 +32,19 @@ type archiver interface { - } - - // helper functions to extract or archive --func extractArchive(i interface{}, src io.Reader, dst string, opts *archive.TarOptions) error { -+func extractArchive(i interface{}, src io.Reader, dst string, opts *archive.TarOptions, root string) error { - if ea, ok := i.(extractor); ok { - return ea.ExtractArchive(src, dst, opts) - } -- return chrootarchive.Untar(src, dst, opts) -+ -+ return chrootarchive.UntarWithRoot(src, dst, opts, root) - } - --func archivePath(i interface{}, src string, opts *archive.TarOptions) (io.ReadCloser, error) { -+func archivePath(i interface{}, src string, opts *archive.TarOptions, root string) (io.ReadCloser, error) { - if ap, ok := i.(archiver); ok { - return ap.ArchivePath(src, opts) - } -- return archive.TarWithOptions(src, opts) -+ return chrootarchive.Tar(src, opts, root) - } - - // ContainerCopy performs a deprecated operation of archiving the resource at -@@ -251,7 +252,7 @@ func (daemon *Daemon) containerArchivePath(container *container.Container, path - sourceDir, sourceBase := driver.Dir(resolvedPath), driver.Base(resolvedPath) - opts := archive.TarResourceRebaseOpts(sourceBase, driver.Base(absPath)) - -- data, err := archivePath(driver, sourceDir, opts) -+ data, err := archivePath(driver, sourceDir, opts, container.BaseFS.Path()) - if err != nil { - return nil, nil, err - } -@@ -380,7 +381,7 @@ func (daemon *Daemon) containerExtractToDir(container *container.Container, path - } - } - -- if err := extractArchive(driver, content, resolvedPath, options); err != nil { -+ if err := extractArchive(driver, content, resolvedPath, options, container.BaseFS.Path()); err != nil { - return err - } - -@@ -445,7 +446,7 @@ func (daemon *Daemon) containerCopy(container *container.Container, resource str - archive, err := archivePath(driver, basePath, &archive.TarOptions{ - Compression: archive.Uncompressed, - IncludeFiles: filter, -- }) -+ }, container.BaseFS.Path()) - if err != nil { - return nil, err - } -diff --git a/components/engine/daemon/export.go b/components/engine/daemon/export.go -index 27bc35967d..01593f4e8a 100644 ---- a/components/engine/daemon/export.go -+++ b/components/engine/daemon/export.go -@@ -70,7 +70,7 @@ func (daemon *Daemon) containerExport(container *container.Container) (arch io.R - Compression: archive.Uncompressed, - UIDMaps: daemon.idMapping.UIDs(), - GIDMaps: daemon.idMapping.GIDs(), -- }) -+ }, basefs.Path()) - if err != nil { - rwlayer.Unmount() - return nil, err -diff --git a/components/engine/pkg/chrootarchive/archive.go b/components/engine/pkg/chrootarchive/archive.go -index 2d9d662830..02fb2de6b2 100644 ---- a/components/engine/pkg/chrootarchive/archive.go -+++ b/components/engine/pkg/chrootarchive/archive.go -@@ -27,18 +27,34 @@ func NewArchiver(idMapping *idtools.IdentityMapping) *archive.Archiver { - // The archive may be compressed with one of the following algorithms: - // identity (uncompressed), gzip, bzip2, xz. - func Untar(tarArchive io.Reader, dest string, options *archive.TarOptions) error { -- return untarHandler(tarArchive, dest, options, true) -+ return untarHandler(tarArchive, dest, options, true, dest) -+} -+ -+// UntarWithRoot is the same as `Untar`, but allows you to pass in a root directory -+// The root directory is the directory that will be chrooted to. -+// `dest` must be a path within `root`, if it is not an error will be returned. -+// -+// `root` should set to a directory which is not controlled by any potentially -+// malicious process. -+// -+// This should be used to prevent a potential attacker from manipulating `dest` -+// such that it would provide access to files outside of `dest` through things -+// like symlinks. Normally `ResolveSymlinksInScope` would handle this, however -+// sanitizing symlinks in this manner is inherrently racey: -+// ref: CVE-2018-15664 -+func UntarWithRoot(tarArchive io.Reader, dest string, options *archive.TarOptions, root string) error { -+ return untarHandler(tarArchive, dest, options, true, root) - } - - // UntarUncompressed reads a stream of bytes from `archive`, parses it as a tar archive, - // and unpacks it into the directory at `dest`. - // The archive must be an uncompressed stream. - func UntarUncompressed(tarArchive io.Reader, dest string, options *archive.TarOptions) error { -- return untarHandler(tarArchive, dest, options, false) -+ return untarHandler(tarArchive, dest, options, false, dest) - } - - // Handler for teasing out the automatic decompression --func untarHandler(tarArchive io.Reader, dest string, options *archive.TarOptions, decompress bool) error { -+func untarHandler(tarArchive io.Reader, dest string, options *archive.TarOptions, decompress bool, root string) error { - if tarArchive == nil { - return fmt.Errorf("Empty archive") - } -@@ -69,5 +85,13 @@ func untarHandler(tarArchive io.Reader, dest string, options *archive.TarOptions - r = decompressedArchive - } - -- return invokeUnpack(r, dest, options) -+ return invokeUnpack(r, dest, options, root) -+} -+ -+// Tar tars the requested path while chrooted to the specified root. -+func Tar(srcPath string, options *archive.TarOptions, root string) (io.ReadCloser, error) { -+ if options == nil { -+ options = &archive.TarOptions{} -+ } -+ return invokePack(srcPath, options, root) - } -diff --git a/components/engine/pkg/chrootarchive/archive_unix.go b/components/engine/pkg/chrootarchive/archive_unix.go -index 5df8afd662..27e7e99e97 100644 ---- a/components/engine/pkg/chrootarchive/archive_unix.go -+++ b/components/engine/pkg/chrootarchive/archive_unix.go -@@ -10,10 +10,13 @@ import ( - "io" - "io/ioutil" - "os" -+ "path/filepath" - "runtime" -+ "strings" - - "github.com/docker/docker/pkg/archive" - "github.com/docker/docker/pkg/reexec" -+ "github.com/pkg/errors" - ) - - // untar is the entry-point for docker-untar on re-exec. This is not used on -@@ -23,18 +26,28 @@ func untar() { - runtime.LockOSThread() - flag.Parse() - -- var options *archive.TarOptions -+ var options archive.TarOptions - - //read the options from the pipe "ExtraFiles" - if err := json.NewDecoder(os.NewFile(3, "options")).Decode(&options); err != nil { - fatal(err) - } - -- if err := chroot(flag.Arg(0)); err != nil { -+ dst := flag.Arg(0) -+ var root string -+ if len(flag.Args()) > 1 { -+ root = flag.Arg(1) -+ } -+ -+ if root == "" { -+ root = dst -+ } -+ -+ if err := chroot(root); err != nil { - fatal(err) - } - -- if err := archive.Unpack(os.Stdin, "/", options); err != nil { -+ if err := archive.Unpack(os.Stdin, dst, &options); err != nil { - fatal(err) - } - // fully consume stdin in case it is zero padded -@@ -45,7 +58,10 @@ func untar() { - os.Exit(0) - } - --func invokeUnpack(decompressedArchive io.Reader, dest string, options *archive.TarOptions) error { -+func invokeUnpack(decompressedArchive io.Reader, dest string, options *archive.TarOptions, root string) error { -+ if root == "" { -+ return errors.New("must specify a root to chroot to") -+ } - - // We can't pass a potentially large exclude list directly via cmd line - // because we easily overrun the kernel's max argument/environment size -@@ -57,7 +73,21 @@ func invokeUnpack(decompressedArchive io.Reader, dest string, options *archive.T - return fmt.Errorf("Untar pipe failure: %v", err) - } - -- cmd := reexec.Command("docker-untar", dest) -+ if root != "" { -+ relDest, err := filepath.Rel(root, dest) -+ if err != nil { -+ return err -+ } -+ if relDest == "." { -+ relDest = "/" -+ } -+ if relDest[0] != '/' { -+ relDest = "/" + relDest -+ } -+ dest = relDest -+ } -+ -+ cmd := reexec.Command("docker-untar", dest, root) - cmd.Stdin = decompressedArchive - - cmd.ExtraFiles = append(cmd.ExtraFiles, r) -@@ -69,6 +99,7 @@ func invokeUnpack(decompressedArchive io.Reader, dest string, options *archive.T - w.Close() - return fmt.Errorf("Untar error on re-exec cmd: %v", err) - } -+ - //write the options to the pipe for the untar exec to read - if err := json.NewEncoder(w).Encode(options); err != nil { - w.Close() -@@ -86,3 +117,92 @@ func invokeUnpack(decompressedArchive io.Reader, dest string, options *archive.T - } - return nil - } -+ -+func tar() { -+ runtime.LockOSThread() -+ flag.Parse() -+ -+ src := flag.Arg(0) -+ var root string -+ if len(flag.Args()) > 1 { -+ root = flag.Arg(1) -+ } -+ -+ if root == "" { -+ root = src -+ } -+ -+ if err := realChroot(root); err != nil { -+ fatal(err) -+ } -+ -+ var options archive.TarOptions -+ if err := json.NewDecoder(os.Stdin).Decode(&options); err != nil { -+ fatal(err) -+ } -+ -+ rdr, err := archive.TarWithOptions(src, &options) -+ if err != nil { -+ fatal(err) -+ } -+ defer rdr.Close() -+ -+ if _, err := io.Copy(os.Stdout, rdr); err != nil { -+ fatal(err) -+ } -+ -+ os.Exit(0) -+} -+ -+func invokePack(srcPath string, options *archive.TarOptions, root string) (io.ReadCloser, error) { -+ if root == "" { -+ return nil, errors.New("root path must not be empty") -+ } -+ -+ relSrc, err := filepath.Rel(root, srcPath) -+ if err != nil { -+ return nil, err -+ } -+ if relSrc == "." { -+ relSrc = "/" -+ } -+ if relSrc[0] != '/' { -+ relSrc = "/" + relSrc -+ } -+ -+ // make sure we didn't trim a trailing slash with the call to `Rel` -+ if strings.HasSuffix(srcPath, "/") && !strings.HasSuffix(relSrc, "/") { -+ relSrc += "/" -+ } -+ -+ cmd := reexec.Command("docker-tar", relSrc, root) -+ -+ errBuff := bytes.NewBuffer(nil) -+ cmd.Stderr = errBuff -+ -+ tarR, tarW := io.Pipe() -+ cmd.Stdout = tarW -+ -+ stdin, err := cmd.StdinPipe() -+ if err != nil { -+ return nil, errors.Wrap(err, "error getting options pipe for tar process") -+ } -+ -+ if err := cmd.Start(); err != nil { -+ return nil, errors.Wrap(err, "tar error on re-exec cmd") -+ } -+ -+ go func() { -+ err := cmd.Wait() -+ err = errors.Wrapf(err, "error processing tar file: %s", errBuff) -+ tarW.CloseWithError(err) -+ }() -+ -+ if err := json.NewEncoder(stdin).Encode(options); err != nil { -+ stdin.Close() -+ return nil, errors.Wrap(err, "tar json encode to pipe failed") -+ } -+ stdin.Close() -+ -+ return tarR, nil -+} -diff --git a/components/engine/pkg/chrootarchive/archive_unix_test.go b/components/engine/pkg/chrootarchive/archive_unix_test.go -new file mode 100644 -index 0000000000..f39a88ad38 ---- /dev/null -+++ b/components/engine/pkg/chrootarchive/archive_unix_test.go -@@ -0,0 +1,171 @@ -+// +build !windows -+ -+package chrootarchive -+ -+import ( -+ gotar "archive/tar" -+ "bytes" -+ "io" -+ "io/ioutil" -+ "os" -+ "path" -+ "path/filepath" -+ "strings" -+ "testing" -+ -+ "github.com/docker/docker/pkg/archive" -+ "golang.org/x/sys/unix" -+ "gotest.tools/assert" -+) -+ -+// Test for CVE-2018-15664 -+// Assures that in the case where an "attacker" controlled path is a symlink to -+// some path outside of a container's rootfs that we do not copy data to a -+// container path that will actually overwrite data on the host -+func TestUntarWithMaliciousSymlinks(t *testing.T) { -+ dir, err := ioutil.TempDir("", t.Name()) -+ assert.NilError(t, err) -+ defer os.RemoveAll(dir) -+ -+ root := filepath.Join(dir, "root") -+ -+ err = os.MkdirAll(root, 0755) -+ assert.NilError(t, err) -+ -+ // Add a file into a directory above root -+ // Ensure that we can't access this file while tarring. -+ err = ioutil.WriteFile(filepath.Join(dir, "host-file"), []byte("I am a host file"), 0644) -+ assert.NilError(t, err) -+ -+ // Create some data which which will be copied into the "container" root into -+ // the symlinked path. -+ // Before this change, the copy would overwrite the "host" content. -+ // With this change it should not. -+ data := filepath.Join(dir, "data") -+ err = os.MkdirAll(data, 0755) -+ assert.NilError(t, err) -+ err = ioutil.WriteFile(filepath.Join(data, "local-file"), []byte("pwn3d"), 0644) -+ assert.NilError(t, err) -+ -+ safe := filepath.Join(root, "safe") -+ err = unix.Symlink(dir, safe) -+ assert.NilError(t, err) -+ -+ rdr, err := archive.TarWithOptions(data, &archive.TarOptions{IncludeFiles: []string{"local-file"}, RebaseNames: map[string]string{"local-file": "host-file"}}) -+ assert.NilError(t, err) -+ -+ // Use tee to test both the good case and the bad case w/o recreating the archive -+ bufRdr := bytes.NewBuffer(nil) -+ tee := io.TeeReader(rdr, bufRdr) -+ -+ err = UntarWithRoot(tee, safe, nil, root) -+ assert.Assert(t, err != nil) -+ assert.ErrorContains(t, err, "open /safe/host-file: no such file or directory") -+ -+ // Make sure the "host" file is still in tact -+ // Before the fix the host file would be overwritten -+ hostData, err := ioutil.ReadFile(filepath.Join(dir, "host-file")) -+ assert.NilError(t, err) -+ assert.Equal(t, string(hostData), "I am a host file") -+ -+ // Now test by chrooting to an attacker controlled path -+ // This should succeed as is and overwrite a "host" file -+ // Note that this would be a mis-use of this function. -+ err = UntarWithRoot(bufRdr, safe, nil, safe) -+ assert.NilError(t, err) -+ -+ hostData, err = ioutil.ReadFile(filepath.Join(dir, "host-file")) -+ assert.NilError(t, err) -+ assert.Equal(t, string(hostData), "pwn3d") -+} -+ -+// Test for CVE-2018-15664 -+// Assures that in the case where an "attacker" controlled path is a symlink to -+// some path outside of a container's rootfs that we do not unwittingly leak -+// host data into the archive. -+func TestTarWithMaliciousSymlinks(t *testing.T) { -+ dir, err := ioutil.TempDir("", t.Name()) -+ assert.NilError(t, err) -+ // defer os.RemoveAll(dir) -+ t.Log(dir) -+ -+ root := filepath.Join(dir, "root") -+ -+ err = os.MkdirAll(root, 0755) -+ assert.NilError(t, err) -+ -+ hostFileData := []byte("I am a host file") -+ -+ // Add a file into a directory above root -+ // Ensure that we can't access this file while tarring. -+ err = ioutil.WriteFile(filepath.Join(dir, "host-file"), hostFileData, 0644) -+ assert.NilError(t, err) -+ -+ safe := filepath.Join(root, "safe") -+ err = unix.Symlink(dir, safe) -+ assert.NilError(t, err) -+ -+ data := filepath.Join(dir, "data") -+ err = os.MkdirAll(data, 0755) -+ assert.NilError(t, err) -+ -+ type testCase struct { -+ p string -+ includes []string -+ } -+ -+ cases := []testCase{ -+ {p: safe, includes: []string{"host-file"}}, -+ {p: safe + "/", includes: []string{"host-file"}}, -+ {p: safe, includes: nil}, -+ {p: safe + "/", includes: nil}, -+ {p: root, includes: []string{"safe/host-file"}}, -+ {p: root, includes: []string{"/safe/host-file"}}, -+ {p: root, includes: nil}, -+ } -+ -+ maxBytes := len(hostFileData) -+ -+ for _, tc := range cases { -+ t.Run(path.Join(tc.p+"_"+strings.Join(tc.includes, "_")), func(t *testing.T) { -+ // Here if we use archive.TarWithOptions directly or change the "root" parameter -+ // to be the same as "safe", data from the host will be leaked into the archive -+ var opts *archive.TarOptions -+ if tc.includes != nil { -+ opts = &archive.TarOptions{ -+ IncludeFiles: tc.includes, -+ } -+ } -+ rdr, err := Tar(tc.p, opts, root) -+ assert.NilError(t, err) -+ defer rdr.Close() -+ -+ tr := gotar.NewReader(rdr) -+ assert.Assert(t, !isDataInTar(t, tr, hostFileData, int64(maxBytes)), "host data leaked to archive") -+ }) -+ } -+} -+ -+func isDataInTar(t *testing.T, tr *gotar.Reader, compare []byte, maxBytes int64) bool { -+ for { -+ h, err := tr.Next() -+ if err == io.EOF { -+ break -+ } -+ assert.NilError(t, err) -+ -+ if h.Size == 0 { -+ continue -+ } -+ assert.Assert(t, h.Size <= maxBytes, "%s: file size exceeds max expected size %d: %d", h.Name, maxBytes, h.Size) -+ -+ data := make([]byte, int(h.Size)) -+ _, err = io.ReadFull(tr, data) -+ assert.NilError(t, err) -+ if bytes.Contains(data, compare) { -+ return true -+ } -+ } -+ -+ return false -+} -diff --git a/components/engine/pkg/chrootarchive/archive_windows.go b/components/engine/pkg/chrootarchive/archive_windows.go -index f2973132a3..de87113e95 100644 ---- a/components/engine/pkg/chrootarchive/archive_windows.go -+++ b/components/engine/pkg/chrootarchive/archive_windows.go -@@ -14,9 +14,16 @@ func chroot(path string) error { - - func invokeUnpack(decompressedArchive io.ReadCloser, - dest string, -- options *archive.TarOptions) error { -+ options *archive.TarOptions, root string) error { - // Windows is different to Linux here because Windows does not support - // chroot. Hence there is no point sandboxing a chrooted process to - // do the unpack. We call inline instead within the daemon process. - return archive.Unpack(decompressedArchive, longpath.AddPrefix(dest), options) - } -+ -+func invokePack(srcPath string, options *archive.TarOptions, root string) (io.ReadCloser, error) { -+ // Windows is different to Linux here because Windows does not support -+ // chroot. Hence there is no point sandboxing a chrooted process to -+ // do the pack. We call inline instead within the daemon process. -+ return archive.TarWithOptions(srcPath, options) -+} -diff --git a/components/engine/pkg/chrootarchive/init_unix.go b/components/engine/pkg/chrootarchive/init_unix.go -index a15e4bb83c..c24fea7d9c 100644 ---- a/components/engine/pkg/chrootarchive/init_unix.go -+++ b/components/engine/pkg/chrootarchive/init_unix.go -@@ -14,6 +14,7 @@ import ( - func init() { - reexec.Register("docker-applyLayer", applyLayer) - reexec.Register("docker-untar", untar) -+ reexec.Register("docker-tar", tar) - } - - func fatal(err error) { --- -2.19.0 - diff --git a/patch/0127-docker-support-docker-cli-using-syslog.patch b/patch/0127-docker-support-docker-cli-using-syslog.patch deleted file mode 100644 index 5028a2e..0000000 --- a/patch/0127-docker-support-docker-cli-using-syslog.patch +++ /dev/null @@ -1,227 +0,0 @@ -From 9b4ec11138037abf3def2fcb1c3f415a915f044e Mon Sep 17 00:00:00 2001 -From: zhaolongquan1 -Date: Thu, 13 Jun 2019 20:49:01 -0400 -Subject: [PATCH] docker: support docker cli using syslog - -reason:add caller information to the docker rm/stop/restart/kill command and print to the log - -Change-Id: I05a109c6a7fe105be6ed680cd5a5700eac99c8bb -Signed-off-by: zhaolongquan1 ---- - .../github.com/docker/docker/pkg/ppid/ppid.go | 41 ++++++++++++++ - .../vendor/github.com/sirupsen/logrus/checklist | 1 + - .../sirupsen/logrus/hooks/syslog/README.md | 39 ++++++++++++++ - .../sirupsen/logrus/hooks/syslog/syslog.go | 62 ++++++++++++++++++++++ - .../sirupsen/logrus/hooks/syslog/syslog_test.go | 27 ++++++++++ - 5 files changed, 170 insertions(+) - create mode 100644 components/cli/vendor/github.com/docker/docker/pkg/ppid/ppid.go - create mode 100644 components/cli/vendor/github.com/sirupsen/logrus/checklist - create mode 100644 components/cli/vendor/github.com/sirupsen/logrus/hooks/syslog/README.md - create mode 100644 components/cli/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go - create mode 100644 components/cli/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go - -diff --git a/components/cli/vendor/github.com/docker/docker/pkg/ppid/ppid.go b/components/cli/vendor/github.com/docker/docker/pkg/ppid/ppid.go -new file mode 100644 -index 0000000..7d634de ---- /dev/null -+++ b/components/cli/vendor/github.com/docker/docker/pkg/ppid/ppid.go -@@ -0,0 +1,41 @@ -+package ppid -+ -+import ( -+ "bytes" -+ "fmt" -+ "io/ioutil" -+ "os" -+ "strings" -+ "log/syslog" -+ -+ "github.com/sirupsen/logrus" -+ lSyslog "github.com/sirupsen/logrus/hooks/syslog" -+) -+ -+func AddSyslogHook() { -+ logrus.SetOutput(ioutil.Discard) -+ hook, serr := lSyslog.NewSyslogHook("", "", syslog.LOG_DEBUG|syslog.LOG_USER, "docker-client") -+ if serr != nil { -+ hook, serr = lSyslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG|syslog.LOG_USER, "docker-client") -+ } -+ if serr == nil { -+ logrus.SetFormatter(&logrus.TextFormatter{ -+ DisableColors: true, -+ FullTimestamp: true, -+ }) -+ logrus.AddHook(hook) -+ } -+} -+ -+func Log(command string, args []string) { -+ ppid := os.Getppid() -+ cmdlinePath := fmt.Sprintf("/proc/%v/cmdline", ppid) -+ content, err := ioutil.ReadFile(cmdlinePath) -+ if err != nil { -+ logrus.Infof("read cmdline %s failed: %v", cmdlinePath, err) -+ } else { -+ s := bytes.Replace(content, []byte{0}, []byte(" "), -1) -+ cmd := fmt.Sprintf("docker %s %v", command, strings.Join(args, " ")) -+ logrus.Infof("received command [%v] from parent [%v] cmdline [%v]", cmd, ppid, string(s)) -+ } -+} -diff --git a/components/cli/vendor/github.com/sirupsen/logrus/checklist b/components/cli/vendor/github.com/sirupsen/logrus/checklist -new file mode 100644 -index 0000000..1d505b2 ---- /dev/null -+++ b/components/cli/vendor/github.com/sirupsen/logrus/checklist -@@ -0,0 +1 @@ -+Add log forwarding mechanism in docker-client and print the ppid for docker kill/restart/stop/rm command. -\ No newline at end of file -diff --git a/components/cli/vendor/github.com/sirupsen/logrus/hooks/syslog/README.md b/components/cli/vendor/github.com/sirupsen/logrus/hooks/syslog/README.md -new file mode 100644 -index 0000000..069ce12 ---- /dev/null -+++ b/components/cli/vendor/github.com/sirupsen/logrus/hooks/syslog/README.md -@@ -0,0 +1,39 @@ -+# Syslog Hooks for Logrus :walrus: -+ -+## Usage -+ -+```go -+import ( -+ "log/syslog" -+ "github.com/sirupsen/logrus" -+ logrus_syslog "github.com/sirupsen/logrus/hooks/syslog" -+) -+ -+func main() { -+ log := logrus.New() -+ hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") -+ -+ if err == nil { -+ log.Hooks.Add(hook) -+ } -+} -+``` -+ -+If you want to connect to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). Just assign empty string to the first two parameters of `NewSyslogHook`. It should look like the following. -+ -+```go -+import ( -+ "log/syslog" -+ "github.com/sirupsen/logrus" -+ logrus_syslog "github.com/sirupsen/logrus/hooks/syslog" -+) -+ -+func main() { -+ log := logrus.New() -+ hook, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO, "") -+ -+ if err == nil { -+ log.Hooks.Add(hook) -+ } -+} -+``` -\ No newline at end of file -diff --git a/components/cli/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go b/components/cli/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go -new file mode 100644 -index 0000000..e76786e ---- /dev/null -+++ b/components/cli/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog.go -@@ -0,0 +1,62 @@ -+// +build !windows,!nacl,!plan9 -+ -+package logrus_syslog -+ -+import ( -+ "fmt" -+ "log/syslog" -+ "os" -+ -+ "github.com/sirupsen/logrus" -+) -+ -+// SyslogHook to send logs via syslog. -+type SyslogHook struct { -+ Writer *syslog.Writer -+ SyslogNetwork string -+ SyslogRaddr string -+} -+ -+// Creates a hook to be added to an instance of logger. This is called with -+// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")` -+// `if err == nil { log.Hooks.Add(hook) }` -+func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) { -+ w, err := syslog.Dial(network, raddr, priority, tag) -+ return &SyslogHook{w, network, raddr}, err -+} -+ -+func (hook *SyslogHook) Fire(entry *logrus.Entry) error { -+ line, err := entry.String() -+ if err != nil { -+ fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err) -+ return err -+ } -+ -+ switch entry.Level { -+ case logrus.PanicLevel: -+ return hook.Writer.Crit(line) -+ case logrus.FatalLevel: -+ return hook.Writer.Crit(line) -+ case logrus.ErrorLevel: -+ return hook.Writer.Err(line) -+ case logrus.WarnLevel: -+ return hook.Writer.Warning(line) -+ case logrus.InfoLevel: -+ return hook.Writer.Info(line) -+ case logrus.DebugLevel: -+ return hook.Writer.Debug(line) -+ default: -+ return nil -+ } -+} -+ -+func (hook *SyslogHook) Levels() []logrus.Level { -+ return []logrus.Level{ -+ logrus.PanicLevel, -+ logrus.FatalLevel, -+ logrus.ErrorLevel, -+ logrus.WarnLevel, -+ logrus.InfoLevel, -+ logrus.DebugLevel, -+ } -+} -diff --git a/components/cli/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go b/components/cli/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go -new file mode 100644 -index 0000000..89bd1ec ---- /dev/null -+++ b/components/cli/vendor/github.com/sirupsen/logrus/hooks/syslog/syslog_test.go -@@ -0,0 +1,27 @@ -+package logrus_syslog -+ -+import ( -+ "log/syslog" -+ "testing" -+ -+ "github.com/sirupsen/logrus" -+) -+ -+func TestLocalhostAddAndPrint(t *testing.T) { -+ log := logrus.New() -+ hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") -+ -+ if err != nil { -+ t.Errorf("Unable to connect to local syslog.") -+ } -+ -+ log.Hooks.Add(hook) -+ -+ for _, level := range hook.Levels() { -+ if len(log.Hooks[level]) != 1 { -+ t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level])) -+ } -+ } -+ -+ log.Info("Congratulations!") -+} --- -1.8.3.1 - diff --git a/patch/0128-docker-add-log-forwarding-mechanism-and-print.patch b/patch/0128-docker-add-log-forwarding-mechanism-and-print.patch deleted file mode 100644 index 0cafa17..0000000 --- a/patch/0128-docker-add-log-forwarding-mechanism-and-print.patch +++ /dev/null @@ -1,103 +0,0 @@ -From ea43c4a77854f15a7782d3acda03b55145796a34 Mon Sep 17 00:00:00 2001 -From: zhaolongquan1 -Date: Thu, 13 Jun 2019 20:56:05 -0400 -Subject: [PATCH] docker: add log forwarding mechanism and print ppid - -reason:add caller information to the docker rm/stop/restart/kill command and print to the log - -Change-Id: I9de1b9ca2ed8b8802362a7cfeb881dbbafbdfe41 -Signed-off-by: zhaolongquan1 ---- - components/cli/cli/command/container/kill.go | 3 +++ - components/cli/cli/command/container/restart.go | 3 +++ - components/cli/cli/command/container/rm.go | 3 +++ - components/cli/cli/command/container/stop.go | 3 +++ - 4 files changed, 12 insertions(+) - -diff --git a/components/cli/cli/command/container/kill.go b/components/cli/cli/command/container/kill.go -index feedbc0..28e7415 100644 ---- a/components/cli/cli/command/container/kill.go -+++ b/components/cli/cli/command/container/kill.go -@@ -3,6 +3,7 @@ package container - import ( - "context" - "fmt" -+ "github.com/docker/docker/pkg/ppid" - "strings" - - "github.com/docker/cli/cli" -@@ -27,6 +28,8 @@ func NewKillCommand(dockerCli command.Cli) *cobra.Command { - Args: cli.RequiresMinArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - opts.containers = args -+ ppid.AddSyslogHook() -+ ppid.Log(cmd.Name(), args) - return runKill(dockerCli, &opts) - }, - } -diff --git a/components/cli/cli/command/container/restart.go b/components/cli/cli/command/container/restart.go -index 6e02ee4..1951f0f 100644 ---- a/components/cli/cli/command/container/restart.go -+++ b/components/cli/cli/command/container/restart.go -@@ -3,6 +3,7 @@ package container - import ( - "context" - "fmt" -+ "github.com/docker/docker/pkg/ppid" - "strings" - "time" - -@@ -30,6 +31,8 @@ func NewRestartCommand(dockerCli command.Cli) *cobra.Command { - RunE: func(cmd *cobra.Command, args []string) error { - opts.containers = args - opts.nSecondsChanged = cmd.Flags().Changed("time") -+ ppid.AddSyslogHook() -+ ppid.Log(cmd.Name(), args) - return runRestart(dockerCli, &opts) - }, - } -diff --git a/components/cli/cli/command/container/rm.go b/components/cli/cli/command/container/rm.go -index 2dcd4b6..29ba403 100644 ---- a/components/cli/cli/command/container/rm.go -+++ b/components/cli/cli/command/container/rm.go -@@ -3,6 +3,7 @@ package container - import ( - "context" - "fmt" -+ "github.com/docker/docker/pkg/ppid" - "strings" - - "github.com/docker/cli/cli" -@@ -30,6 +31,8 @@ func NewRmCommand(dockerCli command.Cli) *cobra.Command { - Args: cli.RequiresMinArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - opts.containers = args -+ ppid.AddSyslogHook() -+ ppid.Log(cmd.Name(), args) - return runRm(dockerCli, &opts) - }, - } -diff --git a/components/cli/cli/command/container/stop.go b/components/cli/cli/command/container/stop.go -index e299175..e6ab748 100644 ---- a/components/cli/cli/command/container/stop.go -+++ b/components/cli/cli/command/container/stop.go -@@ -3,6 +3,7 @@ package container - import ( - "context" - "fmt" -+ "github.com/docker/docker/pkg/ppid" - "strings" - "time" - -@@ -30,6 +31,8 @@ func NewStopCommand(dockerCli command.Cli) *cobra.Command { - RunE: func(cmd *cobra.Command, args []string) error { - opts.containers = args - opts.timeChanged = cmd.Flags().Changed("time") -+ ppid.AddSyslogHook() -+ ppid.Log(cmd.Name(), args) - return runStop(dockerCli, &opts) - }, - } --- -1.8.3.1 - diff --git a/patch/0128-docker-fix-CVE-2019-13509.patch b/patch/0128-docker-fix-CVE-2019-13509.patch deleted file mode 100644 index 23c8513..0000000 --- a/patch/0128-docker-fix-CVE-2019-13509.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 0593b8b0e4279cf015140229795a09df6e3ca8f1 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Mon, 12 Aug 2019 19:13:00 +0800 -Subject: [PATCH] docker: [backport] fix CVE-2019-13509 - -ref: -https://github.com/moby/moby/commit/e4b9edd31fdba3adf1e39fb9874f73d391f0ff34 - -Commit 77b8465d7e68ca102d7aae839c7b3fe0ecd28398 added a secret update -endpoint to allow updating labels on existing secrets. However, when -implementing the endpoint, the DebugRequestMiddleware was not updated -to scrub the Data field (as is being done when creating a secret). - -When updating a secret (to set labels), the Data field should be either -`nil` (not set), or contain the same value as the existing secret. In -situations where the Data field is set, and the `dockerd` daemon is -running with debugging enabled / log-level debug, the base64-encoded -value of the secret is printed to the daemon logs. - -The docker cli does not have a `docker secret update` command, but -when using `docker stack deploy`, the docker cli sends the secret -data both when _creating_ a stack, and when _updating_ a stack, thus -leaking the secret data if the daemon runs with debug enabled: -... - -Signed-off-by: Sebastiaan van Stijn -(cherry picked from commit c7ce4be93ae8edd2da62a588e01c67313a4aba0c) -Signed-off-by: Tibor Vass -(cherry picked from commit 73db8c77bfb2d0cbdf71ce491f3d3e66c9dd5be6) -Signed-off-by: Sebastiaan van Stijn -Upstream-commit: 32b40c53662e733b4627b0b303c71b52484a31f4 - -Change-Id: If571264d227f41cbdcf7dceaa56d7b10ec2a3ee7 -Signed-off-by: jingrui ---- - .../engine/api/server/middleware/debug.go | 24 +++++++++++-------- - 1 file changed, 14 insertions(+), 10 deletions(-) - -diff --git a/components/engine/api/server/middleware/debug.go b/components/engine/api/server/middleware/debug.go -index 2cef1d46c3..31165bf918 100644 ---- a/components/engine/api/server/middleware/debug.go -+++ b/components/engine/api/server/middleware/debug.go -@@ -71,9 +71,22 @@ func maskSecretKeys(inp interface{}, path string) { - } - - if form, ok := inp.(map[string]interface{}); ok { -+ scrub := []string{ -+ // Note: The Data field contains the base64-encoded secret in 'secret' -+ // and 'config' create and update requests. Currently, no other POST -+ // API endpoints use a data field, so we scrub this field unconditionally. -+ // Change this handling to be conditional if a new endpoint is added -+ // in future where this field should not be scrubbed. -+ "data", -+ "jointoken", -+ "password", -+ "secret", -+ "signingcakey", -+ "unlockkey", -+ } - loop0: - for k, v := range form { -- for _, m := range []string{"password", "secret", "jointoken", "unlockkey", "signingcakey"} { -+ for _, m := range scrub { - if strings.EqualFold(m, k) { - form[k] = "*****" - continue loop0 -@@ -81,14 +94,5 @@ func maskSecretKeys(inp interface{}, path string) { - } - maskSecretKeys(v, path) - } -- -- // Route-specific redactions -- if strings.HasSuffix(path, "/secrets/create") { -- for k := range form { -- if k == "Data" { -- form[k] = "*****" -- } -- } -- } - } - } --- -2.17.1 - diff --git a/patch/0129-docker-add-validation-for-ref-CVE-2019-13139.patch b/patch/0129-docker-add-validation-for-ref-CVE-2019-13139.patch deleted file mode 100644 index a8ad5f6..0000000 --- a/patch/0129-docker-add-validation-for-ref-CVE-2019-13139.patch +++ /dev/null @@ -1,92 +0,0 @@ -From b4361679c96219e6f1805cd802ba47a9c9f86f4d Mon Sep 17 00:00:00 2001 -From: build -Date: Mon, 9 Sep 2019 03:13:51 -0400 -Subject: [PATCH] docker: add validation for ref (CVE-2019-13139) - -reason: add validation for ref (CVE-2019-13139) - -Reference from https://github.com/moby/moby/pull/38944 - -Signed-off-by: Tonis Tiigi -Cherry-pick from commit 723b107ca4fba14580a6cd971e63d8af2e7d2bbe -Signed-off-by: Andrew Hsu ---- - .../builder/remotecontext/git/gitutils.go | 6 +++++- - .../remotecontext/git/gitutils_test.go | 21 ++++++++++++++++--- - 2 files changed, 23 insertions(+), 4 deletions(-) - -diff --git a/components/engine/builder/remotecontext/git/gitutils.go b/components/engine/builder/remotecontext/git/gitutils.go -index 77a45be..a907915 100644 ---- a/components/engine/builder/remotecontext/git/gitutils.go -+++ b/components/engine/builder/remotecontext/git/gitutils.go -@@ -102,6 +102,10 @@ func parseRemoteURL(remoteURL string) (gitRepo, error) { - u.Fragment = "" - repo.remote = u.String() - } -+ -+ if strings.HasPrefix(repo.ref, "-") { -+ return gitRepo{}, errors.Errorf("invalid refspec: %s", repo.ref) -+ } - return repo, nil - } - -@@ -124,7 +128,7 @@ func fetchArgs(remoteURL string, ref string) []string { - args = append(args, "--depth", "1") - } - -- return append(args, "origin", ref) -+ return append(args, "origin", "--", ref) - } - - // Check if a given git URL supports a shallow git clone, -diff --git a/components/engine/builder/remotecontext/git/gitutils_test.go b/components/engine/builder/remotecontext/git/gitutils_test.go -index 8c39679..34dd495 100644 ---- a/components/engine/builder/remotecontext/git/gitutils_test.go -+++ b/components/engine/builder/remotecontext/git/gitutils_test.go -@@ -59,7 +59,7 @@ func TestCloneArgsSmartHttp(t *testing.T) { - }) - - args := fetchArgs(serverURL.String(), "master") -- exp := []string{"fetch", "--depth", "1", "origin", "master"} -+ exp := []string{"fetch", "--depth", "1", "origin", "--", "master"} - assert.Check(t, is.DeepEqual(exp, args)) - } - -@@ -75,13 +75,13 @@ func TestCloneArgsDumbHttp(t *testing.T) { - }) - - args := fetchArgs(serverURL.String(), "master") -- exp := []string{"fetch", "origin", "master"} -+ exp := []string{"fetch", "origin", "--", "master"} - assert.Check(t, is.DeepEqual(exp, args)) - } - - func TestCloneArgsGit(t *testing.T) { - args := fetchArgs("git://github.com/docker/docker", "master") -- exp := []string{"fetch", "--depth", "1", "origin", "master"} -+ exp := []string{"fetch", "--depth", "1", "origin", "--", "master"} - assert.Check(t, is.DeepEqual(exp, args)) - } - -@@ -276,3 +276,18 @@ func TestValidGitTransport(t *testing.T) { - } - } - } -+ -+func TestGitInvalidRef(t *testing.T) { -+ gitUrls := []string{ -+ "git://github.com/moby/moby#--foo bar", -+ "git@github.com/moby/moby#--upload-pack=sleep;:", -+ "git@g.com:a/b.git#-B", -+ "git@g.com:a/b.git#with space", -+ } -+ -+ for _, url := range gitUrls { -+ _, err := Clone(url) -+ assert.Assert(t, err != nil) -+ assert.Check(t, is.Contains(strings.ToLower(err.Error()), "invalid refspec")) -+ } -+} --- -2.20.1 - diff --git a/patch/0129-docker-check-if-image-exists-in-memory-when-p.patch b/patch/0129-docker-check-if-image-exists-in-memory-when-p.patch deleted file mode 100644 index 9b899ec..0000000 --- a/patch/0129-docker-check-if-image-exists-in-memory-when-p.patch +++ /dev/null @@ -1,142 +0,0 @@ -From d66866bfd936c50b472c78268eb74ad6999b3490 Mon Sep 17 00:00:00 2001 -From: Fengtu Wang -Date: Sat, 26 Aug 2017 18:55:55 +0800 -Subject: [PATCH] docker: check if image exists in memory when pulling - image - -We only check if imageID exists in disk currently, -but it may not be loaded into memory if it's layer -is broken by some reason. In this case we should not -skip downloading layers and image. - -Change-Id: I9ac2f1aaf20ce618ca9a88613417b757d8d4927e -Signed-off-by: wangfengtu ---- - components/engine/distribution/config.go | 9 +++++++++ - components/engine/distribution/pull_v2.go | 2 +- - components/engine/image/store.go | 13 +++++++++++++ - components/engine/plugin/backend_linux.go | 8 ++++++++ - components/engine/plugin/blobstore.go | 3 +++ - 5 files changed, 34 insertions(+), 1 deletion(-) - -diff --git a/components/engine/distribution/config.go b/components/engine/distribution/config.go -index 211d4f0..00a7c26 100644 ---- a/components/engine/distribution/config.go -+++ b/components/engine/distribution/config.go -@@ -88,6 +88,7 @@ type ImagePushConfig struct { - type ImageConfigStore interface { - Put([]byte) (digest.Digest, error) - Get(digest.Digest) ([]byte, error) -+ GetAndCheck(digest.Digest) ([]byte, error) - RootFSFromConfig([]byte) (*image.RootFS, error) - PlatformFromConfig([]byte) (*specs.Platform, error) - } -@@ -143,6 +144,14 @@ func (s *imageConfigStore) Get(d digest.Digest) ([]byte, error) { - return img.RawJSON(), nil - } - -+func (s *imageConfigStore) GetAndCheck(d digest.Digest) ([]byte, error) { -+ img, err := s.Store.GetAndCheck(image.IDFromDigest(d)) -+ if err != nil { -+ return nil, err -+ } -+ return img.RawJSON(), nil -+} -+ - func (s *imageConfigStore) RootFSFromConfig(c []byte) (*image.RootFS, error) { - var unmarshalledConfig image.Image - if err := json.Unmarshal(c, &unmarshalledConfig); err != nil { -diff --git a/components/engine/distribution/pull_v2.go b/components/engine/distribution/pull_v2.go -index 2c90e2f..9d2a303 100644 ---- a/components/engine/distribution/pull_v2.go -+++ b/components/engine/distribution/pull_v2.go -@@ -555,7 +555,7 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s - } - - target := mfst.Target() -- if img, err := p.config.ImageStore.Get(target.Digest); err == nil { -+ if img, err := p.config.ImageStore.GetAndCheck(target.Digest); err == nil { - rootfs, err := p.config.ImageStore.RootFSFromConfig(img) - if err == nil { - if chainID := rootfs.ChainID(); chainID != "" { -diff --git a/components/engine/image/store.go b/components/engine/image/store.go -index b078a26..db75f06 100644 ---- a/components/engine/image/store.go -+++ b/components/engine/image/store.go -@@ -3,6 +3,7 @@ package image // import "github.com/docker/docker/image" - import ( - "encoding/json" - "fmt" -+ "os" - "sync" - "time" - -@@ -18,6 +19,7 @@ import ( - type Store interface { - Create(config []byte) (ID, error) - Get(id ID) (*Image, error) -+ GetAndCheck(id ID) (*Image, error) - Delete(id ID) ([]layer.Metadata, error) - Search(partialID string) (ID, error) - SetParent(id ID, parent ID) error -@@ -223,6 +225,17 @@ func (is *store) Get(id ID) (*Image, error) { - return img, nil - } - -+func (is *store) GetAndCheck(id ID) (*Image, error) { -+ is.Lock() -+ if is.images[id] == nil { -+ is.Unlock() -+ return nil, os.ErrNotExist -+ } -+ is.Unlock() -+ -+ return is.Get(id) -+} -+ - func (is *store) Delete(id ID) ([]layer.Metadata, error) { - is.Lock() - defer is.Unlock() -diff --git a/components/engine/plugin/backend_linux.go b/components/engine/plugin/backend_linux.go -index e5d3be1..b3116b5 100644 ---- a/components/engine/plugin/backend_linux.go -+++ b/components/engine/plugin/backend_linux.go -@@ -147,6 +147,10 @@ func (s *tempConfigStore) Get(d digest.Digest) ([]byte, error) { - return s.config, nil - } - -+func (s *tempConfigStore) GetAndCheck(d digest.Digest) ([]byte, error) { -+ return s.Get(d) -+} -+ - func (s *tempConfigStore) RootFSFromConfig(c []byte) (*image.RootFS, error) { - return configToRootFS(c) - } -@@ -544,6 +548,10 @@ func (s *pluginConfigStore) Get(d digest.Digest) ([]byte, error) { - return ioutil.ReadAll(rwc) - } - -+func (s *pluginConfigStore) GetAndCheck(d digest.Digest) ([]byte, error) { -+ return s.Get(d) -+} -+ - func (s *pluginConfigStore) RootFSFromConfig(c []byte) (*image.RootFS, error) { - return configToRootFS(c) - } -diff --git a/components/engine/plugin/blobstore.go b/components/engine/plugin/blobstore.go -index a24e7bd..ac6b967 100644 ---- a/components/engine/plugin/blobstore.go -+++ b/components/engine/plugin/blobstore.go -@@ -181,6 +181,9 @@ func (dm *downloadManager) Put(dt []byte) (digest.Digest, error) { - func (dm *downloadManager) Get(d digest.Digest) ([]byte, error) { - return nil, fmt.Errorf("digest not found") - } -+func (dm *downloadManager) GetAndCheck(d digest.Digest) ([]byte, error) { -+ return dm.Get(d) -+} - func (dm *downloadManager) RootFSFromConfig(c []byte) (*image.RootFS, error) { - return configToRootFS(c) - } --- -2.7.4 - diff --git a/patch/0130-docker-Handle-blocked-I-O-of-exec-d-process.patch b/patch/0130-docker-Handle-blocked-I-O-of-exec-d-process.patch deleted file mode 100644 index 6bec743..0000000 --- a/patch/0130-docker-Handle-blocked-I-O-of-exec-d-process.patch +++ /dev/null @@ -1,148 +0,0 @@ -From cd5b236a64426aa7059795afc102110a866df8f0 Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Tue, 5 Nov 2019 03:52:02 +0800 -Subject: [PATCH] docker: [backport] Handle blocked I/O of exec'd processes - -reason: help process delete not block forever when the process exists but the I/O was -inherited by a subprocess that lives on. - -Cherry-pick from upstream https://github.com/moby/moby/pull/39383 - -Change-Id: Ibf8afe3fbfb068a6308565ec1059fc9ef5d6d2e2 -Signed-off-by: xiadanni1 ---- - components/engine/container/container.go | 2 +- - components/engine/container/stream/streams.go | 29 ++++++++++++++++++++++++--- - components/engine/daemon/exec/exec.go | 3 ++- - components/engine/daemon/monitor.go | 6 ++++-- - 4 files changed, 33 insertions(+), 7 deletions(-) - -diff --git a/components/engine/container/container.go b/components/engine/container/container.go -index c194220..81119a0 100644 ---- a/components/engine/container/container.go -+++ b/components/engine/container/container.go -@@ -754,7 +754,7 @@ func (i *rio) Close() error { - } - - func (i *rio) Wait() { -- i.sc.Wait() -+ i.sc.Wait(context.Background()) - - i.IO.Wait() - } -diff --git a/components/engine/container/stream/streams.go b/components/engine/container/stream/streams.go -index d81867c..585f9e8 100644 ---- a/components/engine/container/stream/streams.go -+++ b/components/engine/container/stream/streams.go -@@ -1,6 +1,7 @@ - package stream // import "github.com/docker/docker/container/stream" - - import ( -+ "context" - "fmt" - "io" - "io/ioutil" -@@ -24,11 +25,12 @@ import ( - // copied and delivered to all StdoutPipe and StderrPipe consumers, using - // a kind of "broadcaster". - type Config struct { -- sync.WaitGroup -+ wg sync.WaitGroup - stdout *broadcaster.Unbuffered - stderr *broadcaster.Unbuffered - stdin io.ReadCloser - stdinPipe io.WriteCloser -+ dio *cio.DirectIO - } - - // NewConfig creates a stream config and initializes -@@ -115,14 +117,15 @@ func (c *Config) CloseStreams() error { - - // CopyToPipe connects streamconfig with a libcontainerd.IOPipe - func (c *Config) CopyToPipe(iop *cio.DirectIO) { -+ c.dio = iop - copyFunc := func(w io.Writer, r io.ReadCloser) { -- c.Add(1) -+ c.wg.Add(1) - go func() { - if _, err := pools.Copy(w, r); err != nil { - logrus.Errorf("stream copy error: %v", err) - } - r.Close() -- c.Done() -+ c.wg.Done() - }() - } - -@@ -144,3 +147,23 @@ func (c *Config) CopyToPipe(iop *cio.DirectIO) { - } - } - } -+ -+// Wait for the stream to close -+// Wait supports timeouts via the context to unblock and forcefully -+// close the io streams -+func (c *Config) Wait(ctx context.Context) { -+ done := make(chan struct{}, 1) -+ go func() { -+ c.wg.Wait() -+ close(done) -+ }() -+ select { -+ case <-done: -+ case <-ctx.Done(): -+ if c.dio != nil { -+ c.dio.Cancel() -+ c.dio.Wait() -+ c.dio.Close() -+ } -+ } -+} -diff --git a/components/engine/daemon/exec/exec.go b/components/engine/daemon/exec/exec.go -index c036c46..08fc87c 100644 ---- a/components/engine/daemon/exec/exec.go -+++ b/components/engine/daemon/exec/exec.go -@@ -1,6 +1,7 @@ - package exec // import "github.com/docker/docker/daemon/exec" - - import ( -+ "context" - "runtime" - "sync" - -@@ -58,7 +59,7 @@ func (i *rio) Close() error { - } - - func (i *rio) Wait() { -- i.sc.Wait() -+ i.sc.Wait(context.Background()) - - i.IO.Wait() - } -diff --git a/components/engine/daemon/monitor.go b/components/engine/daemon/monitor.go -index 7ae85f5..e041bd5 100644 ---- a/components/engine/daemon/monitor.go -+++ b/components/engine/daemon/monitor.go -@@ -56,7 +56,8 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerd.EventType, ei libc - logrus.WithError(err).Warnf("failed to delete container %s from containerd", c.ID) - } - -- c.StreamConfig.Wait() -+ ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) -+ c.StreamConfig.Wait(ctx) - c.Reset(false) - - exitStatus := container.ExitStatus{ -@@ -121,7 +122,8 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerd.EventType, ei libc - defer execConfig.Unlock() - execConfig.ExitCode = &ec - execConfig.Running = false -- execConfig.StreamConfig.Wait() -+ ctx, _ := context.WithTimeout(context.Background(), 2*time.Second) -+ execConfig.StreamConfig.Wait(ctx) - if err := execConfig.CloseStreams(); err != nil { - logrus.Errorf("failed to cleanup exec %s streams: %s", c.ID, err) - } --- -1.8.3.1 - diff --git a/patch/0130-docker-mask-internal-proc-add-livepatch.patch b/patch/0130-docker-mask-internal-proc-add-livepatch.patch deleted file mode 100644 index 11b7fa2..0000000 --- a/patch/0130-docker-mask-internal-proc-add-livepatch.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 6eda894b741eb1a0fe10c5834c0bbb81222d3131 Mon Sep 17 00:00:00 2001 -From: wujibin -Date: Fri, 14 Jun 2019 12:51:01 +0800 -Subject: [PATCH] docker: mask internal proc add livepatch - -reason: mask /proc/livepatch - -Change-Id: I229ee5aaccbd067aecb7decce9a7f701531b037a -Signed-off-by: wujibin ---- - .../cli/vendor/github.com/containerd/containerd/oci/spec.go | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/components/cli/vendor/github.com/containerd/containerd/oci/spec.go b/components/cli/vendor/github.com/containerd/containerd/oci/spec.go -index bc5cc45c16..e96c77aad7 100644 ---- a/components/cli/vendor/github.com/containerd/containerd/oci/spec.go -+++ b/components/cli/vendor/github.com/containerd/containerd/oci/spec.go -@@ -228,6 +228,7 @@ func populateDefaultUnixSpec(ctx context.Context, s *Spec, id string) error { - "/proc/cpuirqstat", - "/proc/memstat", - "/proc/iomem_ext", -+ "/proc/livepatch", - }, - ReadonlyPaths: []string{ - "/proc/asound", --- -2.19.0 - diff --git a/patch/0131-docker-fix-mount-loop-on-docker-cp.patch b/patch/0131-docker-fix-mount-loop-on-docker-cp.patch deleted file mode 100644 index 1631a14..0000000 --- a/patch/0131-docker-fix-mount-loop-on-docker-cp.patch +++ /dev/null @@ -1,138 +0,0 @@ -From cdcaf9f39ebde63ed3fce4d062224e4198589368 Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Mon, 9 Dec 2019 04:02:10 -0500 -Subject: [PATCH] docker: fix mount loop on "docker cp" - -reason: fix mount loop on "docker cp" -Cherry-pick from upstream: https://github.com/moby/moby/pull/38993 ---- - components/engine/container/container_unix.go | 9 ++++++++- - components/engine/daemon/archive.go | 15 +++++++++++++-- - components/engine/daemon/volumes_unix.go | 9 +++++++++ - components/engine/pkg/mount/mount.go | 5 +++++ - 4 files changed, 35 insertions(+), 3 deletions(-) - -diff --git a/components/engine/container/container_unix.go b/components/engine/container/container_unix.go -index 5a21b8c..43dd759 100644 ---- a/components/engine/container/container_unix.go -+++ b/components/engine/container/container_unix.go -@@ -385,7 +385,14 @@ func (container *Container) DetachAndUnmount(volumeEventLog func(name, action st - logrus.Warnf("%s unmountVolumes: Failed to do lazy umount fo volume '%s': %v", container.ID, mountPath, err) - } - } -- return container.UnmountVolumes(volumeEventLog) -+ err := container.UnmountVolumes(volumeEventLog) -+ // (daemon *).mountVolumes() calls mount.MakeMountAndRUnbindable() for -+ // container root, which results in an extra bind mount, unmount it. -+ if root, err := container.GetResourcePath(""); err == nil { -+ mount.Unmount(root) -+ } -+ -+ return err - } - - // copyExistingContents copies from the source to the destination and -diff --git a/components/engine/daemon/archive.go b/components/engine/daemon/archive.go -index 0053e53..0bac763 100644 ---- a/components/engine/daemon/archive.go -+++ b/components/engine/daemon/archive.go -@@ -12,6 +12,7 @@ import ( - "github.com/docker/docker/pkg/archive" - "github.com/docker/docker/pkg/chrootarchive" - "github.com/docker/docker/pkg/ioutils" -+ "github.com/docker/docker/pkg/mount" - "github.com/docker/docker/pkg/system" - "github.com/pkg/errors" - ) -@@ -172,6 +173,9 @@ func (daemon *Daemon) containerStatPath(container *container.Container, path str - defer daemon.Unmount(container) - - err = daemon.mountVolumes(container) -+ if err == mount.ErrMountAndRUnbindFailed { -+ return nil, err -+ } - defer container.DetachAndUnmount(daemon.LogVolumeEvent) - if err != nil { - return nil, err -@@ -208,9 +212,11 @@ func (daemon *Daemon) containerArchivePath(container *container.Container, path - } - - defer func() { -- if err != nil { -+ if err != nil && err != mount.ErrMountAndRUnbindFailed { - // unmount any volumes - container.DetachAndUnmount(daemon.LogVolumeEvent) -+ } -+ if err != nil { - // unmount the container's rootfs - daemon.Unmount(container) - } -@@ -286,6 +292,9 @@ func (daemon *Daemon) containerExtractToDir(container *container.Container, path - defer daemon.Unmount(container) - - err = daemon.mountVolumes(container) -+ if err == mount.ErrMountAndRUnbindFailed { -+ return err -+ } - defer container.DetachAndUnmount(daemon.LogVolumeEvent) - if err != nil { - return err -@@ -410,9 +419,11 @@ func (daemon *Daemon) containerCopy(container *container.Container, resource str - } - - defer func() { -- if err != nil { -+ if err != nil && err != mount.ErrMountAndRUnbindFailed { - // unmount any volumes - container.DetachAndUnmount(daemon.LogVolumeEvent) -+ } -+ if err != nil { - // unmount the container's rootfs - daemon.Unmount(container) - } -diff --git a/components/engine/daemon/volumes_unix.go b/components/engine/daemon/volumes_unix.go -index 5ddb926..e9a6d37 100644 ---- a/components/engine/daemon/volumes_unix.go -+++ b/components/engine/daemon/volumes_unix.go -@@ -109,6 +109,15 @@ func setBindModeIfNull(bind *volumemounts.MountPoint) { - } - - func (daemon *Daemon) mountVolumes(container *container.Container) error { -+ if root, err := container.GetResourcePath(""); err == nil { -+ err = mount.ForceMount(root, root, "none", "bind") -+ if err != nil { -+ return mount.ErrMountAndRUnbindFailed -+ } else { -+ mount.ForceMount("", root, "none", "runbindable") -+ } -+ } -+ - mounts, err := daemon.setupMounts(container) - if err != nil { - return err -diff --git a/components/engine/pkg/mount/mount.go b/components/engine/pkg/mount/mount.go -index 874aff6..a784e0d 100644 ---- a/components/engine/pkg/mount/mount.go -+++ b/components/engine/pkg/mount/mount.go -@@ -1,6 +1,7 @@ - package mount // import "github.com/docker/docker/pkg/mount" - - import ( -+ "errors" - "sort" - "strings" - "syscall" -@@ -8,6 +9,10 @@ import ( - "github.com/sirupsen/logrus" - ) - -+var ( -+ ErrMountAndRUnbindFailed = errors.New("make mount and runbind failed") -+) -+ - // FilterFunc is a type defining a callback function - // to filter out unwanted entries. It takes a pointer - // to an Info struct (not fully populated, currently --- -2.20.1 - diff --git a/patch/0132-docker-fix-docker-cp-when-container-source-path-is-root.patch b/patch/0132-docker-fix-docker-cp-when-container-source-path-is-root.patch deleted file mode 100644 index 7a51ce3..0000000 --- a/patch/0132-docker-fix-docker-cp-when-container-source-path-is-root.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 10fedb9c9814c584ceabfd966fa9cdbeb98ba587 Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Tue, 10 Dec 2019 03:44:18 -0500 -Subject: [PATCH] docker: fix docker cp when container source path is / - -reason: fix docker cp when container source path is / -Cherry-pick from upstream: https://github.com/moby/moby/pull/39357 ---- - components/engine/daemon/archive.go | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/components/engine/daemon/archive.go b/components/engine/daemon/archive.go -index 0bac763..f9c6fc7 100644 ---- a/components/engine/daemon/archive.go -+++ b/components/engine/daemon/archive.go -@@ -255,7 +255,11 @@ func (daemon *Daemon) containerArchivePath(container *container.Container, path - if driver.Base(resolvedPath) == "." { - resolvedPath += string(driver.Separator()) + "." - } -- sourceDir, sourceBase := driver.Dir(resolvedPath), driver.Base(resolvedPath) -+ sourceDir := resolvedPath -+ sourceBase := "." -+ if stat.Mode&os.ModeDir == 0 { // not dir -+ sourceDir, sourceBase = driver.Split(resolvedPath) -+ } - opts := archive.TarResourceRebaseOpts(sourceBase, driver.Base(absPath)) - - data, err := archivePath(driver, sourceDir, opts, container.BaseFS.Path()) -@@ -450,9 +454,6 @@ func (daemon *Daemon) containerCopy(container *container.Container, resource str - d, f := driver.Split(basePath) - basePath = d - filter = []string{f} -- } else { -- filter = []string{driver.Base(basePath)} -- basePath = driver.Dir(basePath) - } - archive, err := archivePath(driver, basePath, &archive.TarOptions{ - Compression: archive.Uncompressed, --- -2.20.1 - diff --git a/patch/0132-docker-fix-docker-pull-406-error-on-some-regi.patch b/patch/0132-docker-fix-docker-pull-406-error-on-some-regi.patch deleted file mode 100644 index 32e3b3c..0000000 --- a/patch/0132-docker-fix-docker-pull-406-error-on-some-regi.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 9ef1eaf3c58ec9474ae717c9dd118af347cbd33f Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 19 Jun 2019 23:53:48 +0800 -Subject: [PATCH] docker: fix docker pull 406 error on some registry - -Change-Id: I7047c2cd4f59167fa692c333bda89d224bf84147 -Signed-off-by: jingrui ---- - .../engine/vendor/github.com/docker/distribution/manifests.go | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/components/engine/vendor/github.com/docker/distribution/manifests.go b/components/engine/vendor/github.com/docker/distribution/manifests.go -index 1816baea1d..fb07c92eb5 100644 ---- a/components/engine/vendor/github.com/docker/distribution/manifests.go -+++ b/components/engine/vendor/github.com/docker/distribution/manifests.go -@@ -4,6 +4,7 @@ import ( - "context" - "fmt" - "mime" -+ "sort" - - "github.com/opencontainers/go-digest" - ) -@@ -81,6 +82,7 @@ func ManifestMediaTypes() (mediaTypes []string) { - mediaTypes = append(mediaTypes, t) - } - } -+ sort.Strings(mediaTypes) - return - } - --- -2.17.1 - diff --git a/patch/0133-docker-Fixed-docker-ps-and-docker-inspect-sta.patch b/patch/0133-docker-Fixed-docker-ps-and-docker-inspect-sta.patch deleted file mode 100644 index 27b27b2..0000000 --- a/patch/0133-docker-Fixed-docker-ps-and-docker-inspect-sta.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 4e614995fea775779078f1903fc45bc89e2afe4e Mon Sep 17 00:00:00 2001 -Date: Wed, 26 Jun 2019 12:00:39 +0800 -Subject: [PATCH] docker: Fixed "docker ps" and "docker inspect" - status inconsistency. - -reason: fixed "docker ps" and "docker inspect" status inconsistency. -The SaveFlag is marked when toDisk is failed. Using this flag to -retrycheckpoint. - -Change-Id: I9ea160233043964e48ea0ff2f384f64bac921312 -Signed-off-by: panwenxiang ---- - components/engine/container/container.go | 21 +++++++++++++++++++++ - components/engine/daemon/stop.go | 3 +++ - 2 files changed, 24 insertions(+) - -diff --git a/components/engine/container/container.go b/components/engine/container/container.go -index 02adc20..c194220 100644 ---- a/components/engine/container/container.go -+++ b/components/engine/container/container.go -@@ -11,6 +11,7 @@ import ( - "runtime" - "strings" - "sync" -+ "sync/atomic" - "syscall" - "time" - -@@ -57,6 +58,12 @@ type ExitStatus struct { - ExitedAt time.Time - } - -+const ( -+ SaveSuccess = iota -+ SaveFailed -+ SavePending -+) -+ - // Container holds the structure defining a container object. - type Container struct { - StreamConfig *stream.Config -@@ -109,6 +116,7 @@ type Container struct { - // Fields here are specific to Windows - NetworkSharedContainerID string `json:"-"` - SharedEndpointList []string `json:"-"` -+ SaveFlag int32 - } - - // NewBaseContainer creates a new container with its -@@ -194,10 +202,23 @@ func (container *Container) toDisk() (*Container, error) { - func (container *Container) CheckpointTo(store ViewDB) error { - deepCopy, err := container.toDisk() - if err != nil { -+ atomic.StoreInt32(&container.SaveFlag, SaveFailed) - return err - } - return store.Save(deepCopy) - } -+func (container *Container) RetryCheckPoint(store ViewDB) error { -+ if atomic.CompareAndSwapInt32(&container.SaveFlag, SaveFailed, SavePending) { -+ container.Lock() -+ defer container.Unlock() -+ err := container.CheckpointTo(store) -+ if err != nil { -+ return err -+ } -+ atomic.StoreInt32(&container.SaveFlag, SaveSuccess) -+ } -+ return nil -+} - - // readHostConfig reads the host configuration from disk for the container. - func (container *Container) readHostConfig() error { -diff --git a/components/engine/daemon/stop.go b/components/engine/daemon/stop.go -index 3c4cd76..40bc36d 100644 ---- a/components/engine/daemon/stop.go -+++ b/components/engine/daemon/stop.go -@@ -23,6 +23,9 @@ func (daemon *Daemon) ContainerStop(name string, timeout *int) error { - if err != nil { - return err - } -+ defer func() { -+ go container.RetryCheckPoint(daemon.containersReplica) -+ }() - if !container.IsRunning() { - return containerNotModifiedError{running: false} - } --- -2.1.3 - diff --git a/patch/0135-docker-delete-containerd-db-first-reboot.patch b/patch/0135-docker-delete-containerd-db-first-reboot.patch deleted file mode 100644 index 9ccc655..0000000 --- a/patch/0135-docker-delete-containerd-db-first-reboot.patch +++ /dev/null @@ -1,60 +0,0 @@ -From cb7ce3076d0ae553bd2a2aa64a9be145c144d1ed Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 27 Jun 2019 17:07:21 +0800 -Subject: [PATCH] docker: delete containerd db first reboot - -Change-Id: I90b5e2217df47cef71a410e43188476be751cebe -Signed-off-by: jingrui ---- - components/engine/cmd/dockerd/daemon.go | 1 + - components/engine/daemon/daemon.go | 15 ++++++++++++++- - 2 files changed, 15 insertions(+), 1 deletion(-) - -diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go -index ea00c56fde..9c2b6602b3 100644 ---- a/components/engine/cmd/dockerd/daemon.go -+++ b/components/engine/cmd/dockerd/daemon.go -@@ -185,6 +185,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { - return fmt.Errorf("Error starting daemon: %v", err) - } - -+ d.CleanupContainerdDBs() - d.StoreHosts(hosts) - - // validate after NewDaemon has restored enabled plugins. Dont change order. -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 72467eb62a..c36cc6395f 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -619,6 +619,20 @@ func (daemon *Daemon) cleanupLocalDB(db string) { - } - } - -+func (daemon *Daemon) CleanupContainerdDBs() { -+ // check db lock is exist, do nothing if file is existed -+ dbLockPath := filepath.Join(daemon.configStore.ExecRoot, "dblock") -+ _, err := os.Stat(dbLockPath) -+ if err == nil { -+ return -+ } -+ if !os.IsNotExist(err) { -+ logrus.Errorf("stat dblock failed %v", err) -+ return -+ } -+ daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) -+} -+ - // DB files may corrupted on exception poweroff but can be rebuild at run time, - // so we can remove DB files on OS starts avoid daemon can not startup. - func (daemon *Daemon) cleanupLocalDBs() { -@@ -638,7 +652,6 @@ func (daemon *Daemon) cleanupLocalDBs() { - daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "builder/fscache.db")) - daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "volumes/metadata.db")) - daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "network/files/local-kv.db")) -- // daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) - daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "accelerator/accel.db")) - daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "buildkit/metadata.db")) - daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "buildkit/cache.db")) --- -2.17.1 - diff --git a/patch/0136-docker-continue-to-check-healthy-instead-of-return.patch b/patch/0136-docker-continue-to-check-healthy-instead-of-return.patch deleted file mode 100644 index 58dc9c5..0000000 --- a/patch/0136-docker-continue-to-check-healthy-instead-of-return.patch +++ /dev/null @@ -1,26 +0,0 @@ -From f183e106c38722ba8b02d0ad6da9d8368073a020 Mon Sep 17 00:00:00 2001 -From: yangfeiyu2 -Date: Mon, 1 Jul 2019 01:14:50 -0400 -Subject: [PATCH] docker: continue to check healthy instead of return when setup ExitOnUnhealthy. - - -Signed-off-by: yangfeiyu2 ---- - components/engine/daemon/health.go | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/components/engine/daemon/health.go b/components/engine/daemon/health.go -index 80bda66..5f26ee5 100644 ---- a/components/engine/daemon/health.go -+++ b/components/engine/daemon/health.go -@@ -245,7 +245,6 @@ func monitor(d *Daemon, c *container.Container, stop chan struct{}, probe probe) - c.Config.Healthcheck.ExitOnUnhealthy == true { - d.Kill(c) - logrus.Debugf("Shut down container %s because of unhealthy", c.ID) -- return - } - } - } --- -1.8.3.1 - diff --git a/patch/0137-docker-fix-reboot-dirty-data-in-containerd.patch b/patch/0137-docker-fix-reboot-dirty-data-in-containerd.patch deleted file mode 100644 index 016fcba..0000000 --- a/patch/0137-docker-fix-reboot-dirty-data-in-containerd.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 45c3d6c89fa895f147e74a4388ab604c6c5ad804 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Mon, 1 Jul 2019 21:17:07 +0800 -Subject: [PATCH] docker: fix reboot dirty data in containerd - -Signed-off-by: jingrui ---- - components/engine/cmd/dockerd/daemon.go | 2 +- - components/engine/daemon/daemon.go | 30 ++++++++++++------------- - 2 files changed, 16 insertions(+), 16 deletions(-) - -diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go -index 9c2b6602b3..78cd41ac59 100644 ---- a/components/engine/cmd/dockerd/daemon.go -+++ b/components/engine/cmd/dockerd/daemon.go -@@ -151,6 +151,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { - return fmt.Errorf("Failed to generate containerd options: %v", err) - } - -+ daemon.CleanupContainerdDBs(cli.Config.ExecRoot, cli.Config.Root) - r, err := supervisor.Start(ctx, filepath.Join(cli.Config.Root, "containerd"), filepath.Join(cli.Config.ExecRoot, "containerd"), opts...) - if err != nil { - cancel() -@@ -185,7 +186,6 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { - return fmt.Errorf("Error starting daemon: %v", err) - } - -- d.CleanupContainerdDBs() - d.StoreHosts(hosts) - - // validate after NewDaemon has restored enabled plugins. Dont change order. -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index c36cc6395f..6c5eafd7c5 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -509,7 +509,7 @@ func (daemon *Daemon) restore() error { - logrus.Errorf("removeRedundantMounts failed %v", err) - } - -- daemon.cleanupLocalDBs() -+ daemon.cleanupLocalDBs(daemon.configStore.ExecRoot, daemon.configStore.Root) - - containerIDs := make(map[string]struct{}) - for cid, _ := range containers { -@@ -611,7 +611,7 @@ func (daemon *Daemon) restore() error { - return nil - } - --func (daemon *Daemon) cleanupLocalDB(db string) { -+func cleanupLocalDB(db string) { - _, err := os.Stat(db) - if err == nil { - err = os.Remove(db) -@@ -619,25 +619,25 @@ func (daemon *Daemon) cleanupLocalDB(db string) { - } - } - --func (daemon *Daemon) CleanupContainerdDBs() { -+func CleanupContainerdDBs(run, root string) { - // check db lock is exist, do nothing if file is existed -- dbLockPath := filepath.Join(daemon.configStore.ExecRoot, "dblock") -+ dbLockPath := filepath.Join(run, "dblock") - _, err := os.Stat(dbLockPath) - if err == nil { - return - } - if !os.IsNotExist(err) { -- logrus.Errorf("stat dblock failed %v", err) -+ logrus.Errorf("stat DB dblock failed %v", err) - return - } -- daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) -+ cleanupLocalDB(filepath.Join(root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) - } - - // DB files may corrupted on exception poweroff but can be rebuild at run time, - // so we can remove DB files on OS starts avoid daemon can not startup. --func (daemon *Daemon) cleanupLocalDBs() { -+func (daemon *Daemon) cleanupLocalDBs(run, root string) { - // check db lock is exist, do nothing if file is existed -- dbLockPath := filepath.Join(daemon.configStore.ExecRoot, "dblock") -+ dbLockPath := filepath.Join(run, "dblock") - _, err := os.Stat(dbLockPath) - if err == nil { - return -@@ -649,13 +649,13 @@ func (daemon *Daemon) cleanupLocalDBs() { - ioutil.WriteFile(dbLockPath, []byte{}, 0600) - - removeAllDB := func() { -- daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "builder/fscache.db")) -- daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "volumes/metadata.db")) -- daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "network/files/local-kv.db")) -- daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "accelerator/accel.db")) -- daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "buildkit/metadata.db")) -- daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "buildkit/cache.db")) -- daemon.cleanupLocalDB(filepath.Join(daemon.configStore.Root, "buildkit/snapshots.db")) -+ cleanupLocalDB(filepath.Join(root, "builder/fscache.db")) -+ cleanupLocalDB(filepath.Join(root, "volumes/metadata.db")) -+ cleanupLocalDB(filepath.Join(root, "network/files/local-kv.db")) -+ cleanupLocalDB(filepath.Join(root, "accelerator/accel.db")) -+ cleanupLocalDB(filepath.Join(root, "buildkit/metadata.db")) -+ cleanupLocalDB(filepath.Join(root, "buildkit/cache.db")) -+ cleanupLocalDB(filepath.Join(root, "buildkit/snapshots.db")) - } - - if daemon.containers == nil { --- -2.17.1 - diff --git a/patch/0138-docker-add-loaded-time-to-images-inspect.patch b/patch/0138-docker-add-loaded-time-to-images-inspect.patch deleted file mode 100644 index b7c58e0..0000000 --- a/patch/0138-docker-add-loaded-time-to-images-inspect.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 90345160060de8422eeb8d82b5525b59e31d6a68 Mon Sep 17 00:00:00 2001 -From: yangfeiyu -Date: Mon, 8 Jul 2019 14:45:23 +0800 -Subject: [PATCH] docker: add loaded time to images inspect - -Signed-off-by: yangfeiyu2 - ---- - components/engine/api/types/types.go | 1 + - components/engine/daemon/images/image.go | 13 +++++++++++++ - components/engine/daemon/images/image_inspect.go | 1 + - components/engine/image/fs.go | 9 +++++++++ - components/engine/image/store.go | 5 +++++ - .../engine/integration-cli/docker_cli_save_load_test.go | 8 ++++++-- - 6 files changed, 35 insertions(+), 2 deletions(-) - -diff --git a/components/engine/api/types/types.go b/components/engine/api/types/types.go -index 55955f2..81586e5 100644 ---- a/components/engine/api/types/types.go -+++ b/components/engine/api/types/types.go -@@ -33,6 +33,7 @@ type ImageInspect struct { - Parent string - Comment string - Created string -+ Loaded string - Container string - ContainerConfig *container.Config - DockerVersion string -diff --git a/components/engine/daemon/images/image.go b/components/engine/daemon/images/image.go -index 79cc07c..1536076 100644 ---- a/components/engine/daemon/images/image.go -+++ b/components/engine/daemon/images/image.go -@@ -2,6 +2,8 @@ package images // import "github.com/docker/docker/daemon/images" - - import ( - "fmt" -+ "os" -+ "time" - - "github.com/docker/distribution/reference" - "github.com/docker/docker/errdefs" -@@ -24,6 +26,17 @@ func (e ErrImageDoesNotExist) Error() string { - // NotFound implements the NotFound interface - func (e ErrImageDoesNotExist) NotFound() {} - -+func (i *ImageService) GetImageLoadTime(id image.ID) string { -+ contentFile := i.imageStore.GetContentFile(id) -+ -+ fi, err := os.Stat(contentFile) -+ if err != nil { -+ return "" -+ } -+ -+ return fi.ModTime().Format(time.RFC3339Nano) -+} -+ - // GetImage returns an image corresponding to the image referred to by refOrID. - func (i *ImageService) GetImage(refOrID string) (*image.Image, error) { - ref, err := reference.ParseAnyReference(refOrID) -diff --git a/components/engine/daemon/images/image_inspect.go b/components/engine/daemon/images/image_inspect.go -index 16c4c9b..406cc8d 100644 ---- a/components/engine/daemon/images/image_inspect.go -+++ b/components/engine/daemon/images/image_inspect.go -@@ -70,6 +70,7 @@ func (i *ImageService) LookupImage(name string) (*types.ImageInspect, error) { - Parent: img.Parent.String(), - Comment: comment, - Created: img.Created.Format(time.RFC3339Nano), -+ Loaded: i.GetImageLoadTime(img.ID()), - Container: img.Container, - ContainerConfig: &img.ContainerConfig, - DockerVersion: img.DockerVersion, -diff --git a/components/engine/image/fs.go b/components/engine/image/fs.go -index 7080c8c..06999ea 100644 ---- a/components/engine/image/fs.go -+++ b/components/engine/image/fs.go -@@ -19,6 +19,7 @@ type DigestWalkFunc func(id digest.Digest) error - // StoreBackend provides interface for image.Store persistence - type StoreBackend interface { - Walk(f DigestWalkFunc) error -+ GetContentFile(id digest.Digest) string - Get(id digest.Digest) ([]byte, error) - Set(data []byte) (digest.Digest, error) - Delete(id digest.Digest) error -@@ -86,6 +87,14 @@ func (s *fs) Walk(f DigestWalkFunc) error { - return nil - } - -+// GetContentFile returns the content file path of specified image -+func (s *fs) GetContentFile(id digest.Digest) string { -+ s.RLock() -+ defer s.RUnlock() -+ -+ return s.contentFile(id) -+} -+ - // Get returns the content stored under a given digest. - func (s *fs) Get(dgst digest.Digest) ([]byte, error) { - s.RLock() -diff --git a/components/engine/image/store.go b/components/engine/image/store.go -index db75f06..b31cd4a 100644 ---- a/components/engine/image/store.go -+++ b/components/engine/image/store.go -@@ -19,6 +19,7 @@ import ( - type Store interface { - Create(config []byte) (ID, error) - Get(id ID) (*Image, error) -+ GetContentFile(id ID) string - GetAndCheck(id ID) (*Image, error) - Delete(id ID) ([]layer.Metadata, error) - Search(partialID string) (ID, error) -@@ -225,6 +226,10 @@ func (is *store) Get(id ID) (*Image, error) { - return img, nil - } - -+func (is *store) GetContentFile(id ID) string { -+ return is.fs.GetContentFile(id.Digest()) -+} -+ - func (is *store) GetAndCheck(id ID) (*Image, error) { - is.Lock() - if is.images[id] == nil { -diff --git a/components/engine/integration-cli/docker_cli_save_load_test.go b/components/engine/integration-cli/docker_cli_save_load_test.go -index 688eac6..5fbbfa0 100644 ---- a/components/engine/integration-cli/docker_cli_save_load_test.go -+++ b/components/engine/integration-cli/docker_cli_save_load_test.go -@@ -164,14 +164,18 @@ func (s *DockerSuite) TestSaveAndLoadRepoFlags(c *check.C) { - deleteImages(repoName) - dockerCmd(c, "commit", name, repoName) - -- before, _ := dockerCmd(c, "inspect", repoName) -+ before, _ := RunCommandPipelineWithOutput( -+ exec.Command(dockerBinary, "inspect", repoName), -+ exec.Command("grep", "-v", "Loaded")) - - out, err := RunCommandPipelineWithOutput( - exec.Command(dockerBinary, "save", repoName), - exec.Command(dockerBinary, "load")) - c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err)) - -- after, _ := dockerCmd(c, "inspect", repoName) -+ after, _ := RunCommandPipelineWithOutput( -+ exec.Command(dockerBinary, "inspect", repoName), -+ exec.Command("grep", "-v", "Loaded")) - c.Assert(before, checker.Equals, after, check.Commentf("inspect is not the same after a save / load")) - } - --- -2.6.4.windows.1 - diff --git a/patch/0139-docker-printf-execid-when-task-exit.patch b/patch/0139-docker-printf-execid-when-task-exit.patch deleted file mode 100644 index a027a80..0000000 --- a/patch/0139-docker-printf-execid-when-task-exit.patch +++ /dev/null @@ -1,31 +0,0 @@ -From da2bf67c793393f196effcf0f946e7d108448f4b Mon Sep 17 00:00:00 2001 -From: wujibin -Date: Mon, 22 Jul 2019 11:28:55 +0800 -Subject: [PATCH] docker: printf execid when task exit - -reason: distinguish execid and initid when task exit - -Change-Id: Iff89ab6463135a392560684c156e4dc9bf0150d5 -Signed-off-by: wujibin ---- - components/engine/libcontainerd/client_daemon.go | 1 + - 1 file changed, 1 insertion(+) - mode change 100644 => 100755 components/engine/libcontainerd/client_daemon.go - -diff --git a/components/engine/libcontainerd/client_daemon.go b/components/engine/libcontainerd/client_daemon.go -old mode 100644 -new mode 100755 -index 491bda281c..858d6429f1 ---- a/components/engine/libcontainerd/client_daemon.go -+++ b/components/engine/libcontainerd/client_daemon.go -@@ -828,6 +828,7 @@ func (c *client) processEventStream(ctx context.Context, ns string) { - c.logger.WithFields(logrus.Fields{ - "topic": ev.Topic, - "containerID": t.ContainerID, -+ "ProcessID": t.ID, - "Pid": t.Pid, - "ExitStatus": t.ExitStatus, - "ExitedAt": t.ExitedAt, --- -2.19.0 - diff --git a/patch/0140-docker-add-timestamp-when-setup-iptables.patch b/patch/0140-docker-add-timestamp-when-setup-iptables.patch deleted file mode 100644 index cfd4db6..0000000 --- a/patch/0140-docker-add-timestamp-when-setup-iptables.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 7065246077ffc29990c5d58f3b8452169e3cb38a Mon Sep 17 00:00:00 2001 -From: wujibin -Date: Mon, 22 Jul 2019 16:25:25 +0800 -Subject: [PATCH] docker: add timestamp when setup iptables - -reason: show setup iptables begin and end timestamp for debug - -Change-Id: I1d3996f80aa187772bf7f1ae4ea9b3c9314e0b4e -Signed-off-by: wujibin ---- - .../docker/libnetwork/drivers/bridge/setup_ip_tables.go | 3 +++ - 1 file changed, 3 insertions(+) - mode change 100644 => 100755 components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go - -diff --git a/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go b/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go -old mode 100644 -new mode 100755 -index 5865a18f18..d134857074 ---- a/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go -+++ b/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go -@@ -101,6 +101,9 @@ func (n *bridgeNetwork) setupIPTables(config *networkConfiguration, i *bridgeInt - driverConfig := d.config - d.Unlock() - -+ logrus.Info("Setup IP tables begin") -+ defer logrus.Info("Setup IP tables end") -+ - // Sanity check. - if driverConfig.EnableIPTables == false { - return errors.New("Cannot program chains, EnableIPTable is disabled") --- -2.19.0 - diff --git a/patch/0141-docker-fix-updateUnpauseStats-wrong-path-erro.patch b/patch/0141-docker-fix-updateUnpauseStats-wrong-path-erro.patch deleted file mode 100644 index 3618b6e..0000000 --- a/patch/0141-docker-fix-updateUnpauseStats-wrong-path-erro.patch +++ /dev/null @@ -1,34 +0,0 @@ -From d9b610a415b59f330ca151009434fa83e59cc5e5 Mon Sep 17 00:00:00 2001 -From: lixiang172 -Date: Mon, 12 Aug 2019 09:35:56 +0800 -Subject: [PATCH] docker: fix updateUnpauseStats wrong path error - -reason: The container stats path has changed but the updatePauseStatus -still use old path, so we need to update it in case the error occur - -Change-Id: I309ae2e351eb3b945a23b85841029770b7855da4 ---- - components/engine/daemon/daemon.go | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 6c5eafd..01351cc 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -209,7 +209,12 @@ func (daemon *Daemon) updatePauseStatus(c *container.Container) error { - // update docker pause status. - // for old container, CgroupParent may be empty. - if c.CgroupParent == "" { -- spec, err := libcontainerd.LoadContainerSpec(filepath.Join(daemon.configStore.ExecRoot, "libcontainerd"), c.ID) -+ // for container just be created, the moby path is empty, so just return nil -+ if c.State.StateString() == "created" { -+ return nil -+ } -+ mobyPath := "containerd/daemon/io.containerd.runtime.v1.linux/moby" -+ spec, err := libcontainerd.LoadContainerSpec(filepath.Join(daemon.configStore.ExecRoot, mobyPath), c.ID) - if err != nil { - return err - } --- -1.8.3.1 - diff --git a/patch/0141-docker-remove-logo-info.patch b/patch/0141-docker-remove-logo-info.patch deleted file mode 100644 index aad52bf..0000000 --- a/patch/0141-docker-remove-logo-info.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 817a6a5d7f3bf91a4560deac23a656fa53c16e69 Mon Sep 17 00:00:00 2001 -From: lixiang172 -Date: Thu, 15 Aug 2019 20:24:58 +0800 -Subject: [PATCH] docker: remove logo info - -reason: remove logo info - -Change-Id: I1c0317a027ea277e03cdfafd3d8b85a4efbf3d0a -Signed-off-by: lixiang172 ---- - components/cli/scripts/build/.variables | 2 +- - components/engine/hack/make.sh | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/components/cli/scripts/build/.variables b/components/cli/scripts/build/.variables -index d504032..86d0e3a 100755 ---- a/components/cli/scripts/build/.variables -+++ b/components/cli/scripts/build/.variables -@@ -3,7 +3,7 @@ set -eu - - PLATFORM=${PLATFORM:-} - VERSION=${VERSION:-"unknown-version"} --EULERVERSION=${EULERVERSION:-$(cat VERSION-EULER)} -+EULERVERSION=${EULERVERSION:-$(cat VERSION-openeuler)} - GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)} - BUILDTIME=${BUILDTIME:-$(date --utc --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/')} - -diff --git a/components/engine/hack/make.sh b/components/engine/hack/make.sh -index fa87d91..686e688 100755 ---- a/components/engine/hack/make.sh -+++ b/components/engine/hack/make.sh -@@ -65,7 +65,7 @@ DEFAULT_BUNDLES=( - cross - ) - --VERSION_EULER=$(< ./VERSION-EULER) -+VERSION_EULER=$(< ./VERSION-openeuler) - VERSION=${VERSION:-dev} - ! BUILDTIME=$(date -u -d "@${SOURCE_DATE_EPOCH:-$(date +%s)}" --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/') - if [ "$DOCKER_GITCOMMIT" ]; then --- -1.8.3.1 - diff --git a/patch/0142-docker-add-copyright.patch b/patch/0142-docker-add-copyright.patch deleted file mode 100644 index 23e6c3b..0000000 --- a/patch/0142-docker-add-copyright.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 24c82a1f5e930d34f28843478e03e877ede0ab11 Mon Sep 17 00:00:00 2001 -From: xiadanni -Date: Fri, 30 Aug 2019 02:19:15 +0800 -Subject: [PATCH] docker: add copyright - -reason: add copyright - -Change-Id: I26a1a140e2223646154c0980bc9ec4f0b212f764 -Signed-off-by: xiadanni ---- - components/cli/opts/hugetlb.go | 7 +++++++ - components/engine/pkg/sysinfo/utils_linux.go | 7 ++++++- - components/engine/pkg/trylock/mutex.go | 7 +++++++ - components/engine/utils/utils.go | 7 +++++++ - 4 files changed, 27 insertions(+), 1 deletion(-) - -diff --git a/components/cli/opts/hugetlb.go b/components/cli/opts/hugetlb.go -index 48cfeff..c90a00b 100644 ---- a/components/cli/opts/hugetlb.go -+++ b/components/cli/opts/hugetlb.go -@@ -1,3 +1,10 @@ -+/* -+Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. -+Description: hugetlb related common functions -+Author: zhaolongquan -+Create: 2019-06-12 -+*/ -+ - package opts - - import ( -diff --git a/components/engine/pkg/sysinfo/utils_linux.go b/components/engine/pkg/sysinfo/utils_linux.go -index 905d0b7..e380f7a 100644 ---- a/components/engine/pkg/sysinfo/utils_linux.go -+++ b/components/engine/pkg/sysinfo/utils_linux.go -@@ -1,4 +1,9 @@ --// +build linux -+/* -+Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. -+Description: hugetlb related common functions -+Author: zhaolongquan -+Create: 2019-06-12 -+*/ - - package sysinfo - -diff --git a/components/engine/pkg/trylock/mutex.go b/components/engine/pkg/trylock/mutex.go -index 39fb888..63fba74 100644 ---- a/components/engine/pkg/trylock/mutex.go -+++ b/components/engine/pkg/trylock/mutex.go -@@ -1,3 +1,10 @@ -+/* -+Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. -+Description: mutex related common functions -+Author: lujingxiao -+Create: 2019-01-19 -+*/ -+ - package trylock - - import ( -diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go -index 75fd409..5363a76 100644 ---- a/components/engine/utils/utils.go -+++ b/components/engine/utils/utils.go -@@ -1,3 +1,10 @@ -+/* -+Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. -+Description: common functions -+Author: lujingxiao -+Create: 2019-01-19 -+*/ -+ - package utils - - /* --- -1.8.3.1 - diff --git a/patch/0142-docker-fix-fd-leak-on-reboot.patch b/patch/0142-docker-fix-fd-leak-on-reboot.patch deleted file mode 100644 index 95ddaef..0000000 --- a/patch/0142-docker-fix-fd-leak-on-reboot.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 7a175514804e423257225a33fd7788ddd621e567 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Tue, 3 Sep 2019 16:10:19 +0800 -Subject: [PATCH] docker: fix fd leak on reboot - -The original db cleanup is too late, because docker has opened the db -files. Move it to dockerd start entry. - -Change-Id: I462c6b2fe44a0447fd5cc111f25b2e26b7488dc2 -Signed-off-by: jingrui ---- - components/engine/cmd/dockerd/daemon.go | 35 ++++++++++++- - components/engine/daemon/daemon.go | 68 ------------------------- - 2 files changed, 34 insertions(+), 69 deletions(-) - -diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go -index 78cd41ac59..1981175a4a 100644 ---- a/components/engine/cmd/dockerd/daemon.go -+++ b/components/engine/cmd/dockerd/daemon.go -@@ -4,6 +4,7 @@ import ( - "context" - "crypto/tls" - "fmt" -+ "io/ioutil" - "os" - "path/filepath" - "runtime" -@@ -71,6 +72,38 @@ func NewDaemonCli() *DaemonCli { - return &DaemonCli{} - } - -+func cleanupLocalDB(db string) { -+ _, err := os.Stat(db) -+ if err == nil { -+ err = os.Remove(db) -+ logrus.Infof("cleanup DB %s error=%v", db, err) -+ } -+} -+ -+// DB files may corrupted on exception poweroff but can be rebuild at run time, -+// so we can remove DB files on OS starts avoid daemon can not startup. -+func cleanupLocalDBs(run, root string) { -+ // check db lock is exist, do nothing if file is existed -+ dbLockPath := filepath.Join(run, "dblock") -+ _, err := os.Stat(dbLockPath) -+ if err == nil { -+ return -+ } -+ if !os.IsNotExist(err) { -+ logrus.Errorf("stat dblock failed %v", err) -+ return -+ } -+ ioutil.WriteFile(dbLockPath, []byte{}, 0600) -+ cleanupLocalDB(filepath.Join(root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) -+ cleanupLocalDB(filepath.Join(root, "builder/fscache.db")) -+ cleanupLocalDB(filepath.Join(root, "volumes/metadata.db")) -+ cleanupLocalDB(filepath.Join(root, "network/files/local-kv.db")) -+ cleanupLocalDB(filepath.Join(root, "accelerator/accel.db")) -+ cleanupLocalDB(filepath.Join(root, "buildkit/metadata.db")) -+ cleanupLocalDB(filepath.Join(root, "buildkit/cache.db")) -+ cleanupLocalDB(filepath.Join(root, "buildkit/snapshots.db")) -+} -+ - func (cli *DaemonCli) start(opts *daemonOptions) (err error) { - stopc := make(chan bool) - defer close(stopc) -@@ -151,7 +184,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { - return fmt.Errorf("Failed to generate containerd options: %v", err) - } - -- daemon.CleanupContainerdDBs(cli.Config.ExecRoot, cli.Config.Root) -+ cleanupLocalDBs(cli.Config.ExecRoot, cli.Config.Root) - r, err := supervisor.Start(ctx, filepath.Join(cli.Config.Root, "containerd"), filepath.Join(cli.Config.ExecRoot, "containerd"), opts...) - if err != nil { - cancel() -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 01351cc544..b9af915ef8 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -514,8 +514,6 @@ func (daemon *Daemon) restore() error { - logrus.Errorf("removeRedundantMounts failed %v", err) - } - -- daemon.cleanupLocalDBs(daemon.configStore.ExecRoot, daemon.configStore.Root) -- - containerIDs := make(map[string]struct{}) - for cid, _ := range containers { - containerIDs[cid] = struct{}{} -@@ -616,72 +614,6 @@ func (daemon *Daemon) restore() error { - return nil - } - --func cleanupLocalDB(db string) { -- _, err := os.Stat(db) -- if err == nil { -- err = os.Remove(db) -- logrus.Infof("cleanup DB %s error=%v", db, err) -- } --} -- --func CleanupContainerdDBs(run, root string) { -- // check db lock is exist, do nothing if file is existed -- dbLockPath := filepath.Join(run, "dblock") -- _, err := os.Stat(dbLockPath) -- if err == nil { -- return -- } -- if !os.IsNotExist(err) { -- logrus.Errorf("stat DB dblock failed %v", err) -- return -- } -- cleanupLocalDB(filepath.Join(root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) --} -- --// DB files may corrupted on exception poweroff but can be rebuild at run time, --// so we can remove DB files on OS starts avoid daemon can not startup. --func (daemon *Daemon) cleanupLocalDBs(run, root string) { -- // check db lock is exist, do nothing if file is existed -- dbLockPath := filepath.Join(run, "dblock") -- _, err := os.Stat(dbLockPath) -- if err == nil { -- return -- } -- if !os.IsNotExist(err) { -- logrus.Errorf("stat dblock failed %v", err) -- return -- } -- ioutil.WriteFile(dbLockPath, []byte{}, 0600) -- -- removeAllDB := func() { -- cleanupLocalDB(filepath.Join(root, "builder/fscache.db")) -- cleanupLocalDB(filepath.Join(root, "volumes/metadata.db")) -- cleanupLocalDB(filepath.Join(root, "network/files/local-kv.db")) -- cleanupLocalDB(filepath.Join(root, "accelerator/accel.db")) -- cleanupLocalDB(filepath.Join(root, "buildkit/metadata.db")) -- cleanupLocalDB(filepath.Join(root, "buildkit/cache.db")) -- cleanupLocalDB(filepath.Join(root, "buildkit/snapshots.db")) -- } -- -- if daemon.containers == nil { -- logrus.Warnf("nil containers, cleanup local DB after OS start ...") -- removeAllDB() -- return -- } -- -- ls, err := daemon.Containers(&types.ContainerListOptions{}) -- if err != nil { -- logrus.Errorf("list containers failed %v", err) -- return -- } -- -- if len(ls) == 0 { -- logrus.Warnf("no running containers, cleanup local DB after OS start ...") -- removeAllDB() -- return -- } --} -- - // RestartSwarmContainers restarts any autostart container which has a - // swarm endpoint. - func (daemon *Daemon) RestartSwarmContainers() { --- -2.17.1 - diff --git a/patch/0143-docker-add-exit-on-unhealthy-flag-for-health-check.patch b/patch/0143-docker-add-exit-on-unhealthy-flag-for-health-check.patch deleted file mode 100644 index ad3a26f..0000000 --- a/patch/0143-docker-add-exit-on-unhealthy-flag-for-health-check.patch +++ /dev/null @@ -1,40 +0,0 @@ -From d22a96d286265462f82db6329a555cc4dcf3a99c Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Mon, 14 Oct 2019 23:09:29 -0400 -Subject: [PATCH] docker: add 'exit-on-unhealthy' flag for docker build parse Dockerfile - -reason: add 'exit-on-unhealthy' flag for docker build parse - -Signed-off-by: liuzekun ---- - .../buildkit/frontend/dockerfile/instructions/parse.go | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go -index 0ce076a5..acfd669b 100644 ---- a/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go -+++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go -@@ -449,6 +449,7 @@ func parseHealthcheck(req parseRequest) (*HealthCheckCommand, error) { - flTimeout := req.flags.AddString("timeout", "") - flStartPeriod := req.flags.AddString("start-period", "") - flRetries := req.flags.AddString("retries", "") -+ flExitOnUnhealthy := req.flags.AddBool("exit-on-unhealthy", false) - - if err := req.flags.Parse(); err != nil { - return nil, err -@@ -501,6 +502,12 @@ func parseHealthcheck(req parseRequest) (*HealthCheckCommand, error) { - healthcheck.Retries = 0 - } - -+ exitonunhealthy, err := strconv.ParseBool(flExitOnUnhealthy.Value) -+ if err != nil { -+ return nil, err -+ } -+ healthcheck.ExitOnUnhealthy = exitonunhealthy -+ - cmd.Health = &healthcheck - } - return cmd, nil --- -2.20.1 - diff --git a/patch/0143-docker-add-license.patch b/patch/0143-docker-add-license.patch deleted file mode 100644 index ec876cc..0000000 --- a/patch/0143-docker-add-license.patch +++ /dev/null @@ -1,71 +0,0 @@ -From c6c599d5101ceac3c1ec38aa1b615f6009f4ca19 Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Sat, 7 Sep 2019 00:54:32 +0800 -Subject: [PATCH] docker: add license - -reason: add license - -Change-Id: I82f16e0664010fe4789c5e7ff0daa3460042a341 -Signed-off-by: xiadanni1 ---- - components/cli/opts/hugetlb.go | 4 +++- - components/engine/pkg/sysinfo/utils_linux.go | 4 +++- - components/engine/pkg/trylock/mutex.go | 4 +++- - components/engine/utils/utils.go | 4 +++- - 4 files changed, 12 insertions(+), 4 deletions(-) - -diff --git a/components/cli/opts/hugetlb.go b/components/cli/opts/hugetlb.go -index c90a00b..68b771a 100644 ---- a/components/cli/opts/hugetlb.go -+++ b/components/cli/opts/hugetlb.go -@@ -1,5 +1,7 @@ - /* --Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. -+Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. -+Use of this source code is governed by Apache-2.0 -+license that can be found in the LICENSE file. - Description: hugetlb related common functions - Author: zhaolongquan - Create: 2019-06-12 -diff --git a/components/engine/pkg/sysinfo/utils_linux.go b/components/engine/pkg/sysinfo/utils_linux.go -index e380f7a..fc8f023 100644 ---- a/components/engine/pkg/sysinfo/utils_linux.go -+++ b/components/engine/pkg/sysinfo/utils_linux.go -@@ -1,5 +1,7 @@ - /* --Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. -+Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. -+Use of this source code is governed by Apache-2.0 -+license that can be found in the LICENSE file. - Description: hugetlb related common functions - Author: zhaolongquan - Create: 2019-06-12 -diff --git a/components/engine/pkg/trylock/mutex.go b/components/engine/pkg/trylock/mutex.go -index 63fba74..5069df8 100644 ---- a/components/engine/pkg/trylock/mutex.go -+++ b/components/engine/pkg/trylock/mutex.go -@@ -1,5 +1,7 @@ - /* --Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. -+Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. -+Use of this source code is governed by Apache-2.0 -+license that can be found in the LICENSE file. - Description: mutex related common functions - Author: lujingxiao - Create: 2019-01-19 -diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go -index 5363a76..53893fc 100644 ---- a/components/engine/utils/utils.go -+++ b/components/engine/utils/utils.go -@@ -1,5 +1,7 @@ - /* --Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved. -+Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved. -+Use of this source code is governed by Apache-2.0 -+license that can be found in the LICENSE file. - Description: common functions - Author: lujingxiao - Create: 2019-01-19 --- -1.8.3.1 - diff --git a/patch/0144-docker-fix-testcase-TestAttachClosedOnContain.patch b/patch/0144-docker-fix-testcase-TestAttachClosedOnContain.patch deleted file mode 100644 index 780ca9a..0000000 --- a/patch/0144-docker-fix-testcase-TestAttachClosedOnContain.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 1b8ccbb863368258645e76a85fca202050a9c636 Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Thu, 31 Oct 2019 02:35:33 +0800 -Subject: [PATCH] docker: fix testcase TestAttachClosedOnContainerStop - -reason:testcase TestAttachClosedOnContainerStop will fail because we add timeout -for attach when container stops, in this case we just ignore err. - -Change-Id: I5db1e76535d7a39d3782b488025e27b09e341d3b -Signed-off-by: xiadanni1 ---- - components/engine/integration-cli/docker_cli_attach_unix_test.go | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/components/engine/integration-cli/docker_cli_attach_unix_test.go b/components/engine/integration-cli/docker_cli_attach_unix_test.go -index 9affb94..906bf07 100644 ---- a/components/engine/integration-cli/docker_cli_attach_unix_test.go -+++ b/components/engine/integration-cli/docker_cli_attach_unix_test.go -@@ -52,6 +52,9 @@ func (s *DockerSuite) TestAttachClosedOnContainerStop(c *check.C) { - case err := <-errChan: - tty.Close() - out, _ := ioutil.ReadAll(pty) -+ if strings.Contains(string(out), "Wait container status timeout") { -+ err = nil -+ } - c.Assert(err, check.IsNil, check.Commentf("out: %v", string(out))) - case <-time.After(attachWait): - c.Fatal("timed out without attach returning") --- -1.8.3.1 - diff --git a/patch/0144-docker-hide-some-path-in-container.patch b/patch/0144-docker-hide-some-path-in-container.patch deleted file mode 100644 index 33b4e13..0000000 --- a/patch/0144-docker-hide-some-path-in-container.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 80aa68c35d6199d80a136f480ac8a7fa9ef9146d Mon Sep 17 00:00:00 2001 -From: lixiang -Date: Tue, 17 Sep 2019 22:58:07 +0800 -Subject: [PATCH] docker: mask some path in contianer - -reason: for security reason, we masked the following path to prevent -hackers obtaining the access to the important path on host os. -/proc/cpuirqstat -/proc/memstat -/proc/iomem_ext -/proc/livepatch -/proc/net_namespace - -Change-Id: I394f75e8a277983ad94018e8d51bbddda0f357d7 -Signed-off-by: lixiang ---- - components/engine/oci/defaults.go | 23 ++++++++++++++--------- - 1 file changed, 14 insertions(+), 9 deletions(-) - -diff --git a/components/engine/oci/defaults.go b/components/engine/oci/defaults.go -index 74d3fdb..cd4985f 100644 ---- a/components/engine/oci/defaults.go -+++ b/components/engine/oci/defaults.go -@@ -117,21 +117,26 @@ func DefaultLinuxSpec() specs.Spec { - MaskedPaths: []string{ - "/proc/acpi", - "/proc/config.gz", -+ "/proc/cpuirqstat", -+ "/proc/fdenable", -+ "/proc/fdstat", -+ "/proc/fdthreshold", -+ "/proc/files_panic_enable", -+ "/proc/iomem_ext", -+ "/proc/kbox", - "/proc/kcore", - "/proc/keys", - "/proc/latency_stats", -- "/proc/timer_list", -- "/proc/timer_stats", -+ "/proc/livepatch", -+ "/proc/memstat", -+ "/proc/net_namespace", -+ "/proc/oom_extend", - "/proc/sched_debug", - "/proc/scsi", -- "/proc/files_panic_enable", -- "/proc/fdthreshold", -- "/proc/fdstat", -- "/proc/fdenable", -- "/proc/signo", - "/proc/sig_catch", -- "/proc/kbox", -- "/proc/oom_extend", -+ "/proc/signo", -+ "/proc/timer_list", -+ "/proc/timer_stats", - "/sys/firmware", - }, - ReadonlyPaths: []string{ --- -1.8.3.1 - diff --git a/patch/0145-docker-hot-upgrade-support-default-runtime.patch b/patch/0145-docker-hot-upgrade-support-default-runtime.patch deleted file mode 100644 index 4da8757..0000000 --- a/patch/0145-docker-hot-upgrade-support-default-runtime.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 1479fdcf8c162cb9b0c54673fedba2a2ee2dbf36 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 14 Aug 2019 10:35:30 +0800 -Subject: [PATCH 1/3] docker: hot-upgrade support default runtime - -When hot-upgrade from docker-1.11.2, old version docker using -default runtime for runc. We need support start container created from -old version docker. - -Change-Id: I1287c5a6798be57c8d0446230806dc87c98ab787 -Signed-off-by: jingrui ---- - components/engine/daemon/config/config_common_unix.go | 5 +++++ - components/engine/daemon/daemon.go | 5 ++--- - 2 files changed, 7 insertions(+), 3 deletions(-) - -diff --git a/components/engine/daemon/config/config_common_unix.go b/components/engine/daemon/config/config_common_unix.go -index 0a862d3b50..e2dfec91bb 100644 ---- a/components/engine/daemon/config/config_common_unix.go -+++ b/components/engine/daemon/config/config_common_unix.go -@@ -32,6 +32,11 @@ func (conf *Config) GetRuntime(name string) *types.Runtime { - if rt, ok := conf.Runtimes[name]; ok { - return &rt - } -+ if name == "default" { // legacy docker reserved default for runc. -+ if rt, ok := conf.Runtimes["runc"]; ok { -+ return &rt -+ } -+ } - return nil - } - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index b9af915ef8..3bd0d93a52 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -357,13 +357,12 @@ func (daemon *Daemon) restore() error { - }).Debug("restoring container") - - var ( -- err error -- alive bool - ec uint32 - exitedAt time.Time - ) - -- alive, _, err = daemon.containerd.Restore(context.Background(), c.ID, c.InitializeStdio) -+ alive, pid, err := daemon.containerd.Restore(context.Background(), c.ID, c.InitializeStdio) -+ logrus.Infof("restored %s from containerd alive=%t pid=%d error=%v", c.ID, alive, pid, err) - if err != nil && !errdefs.IsNotFound(err) { - logrus.Errorf("Failed to restore container %s with containerd: %s", c.ID, err) - return --- -2.17.1 - diff --git a/patch/0146-docker-hot-upgrade-support-accel-plugins.patch b/patch/0146-docker-hot-upgrade-support-accel-plugins.patch deleted file mode 100644 index 7e9d08a..0000000 --- a/patch/0146-docker-hot-upgrade-support-accel-plugins.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 475f02ed158e1339114f34fed98aa766e630351b Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Mon, 23 Sep 2019 13:43:44 +0800 -Subject: [PATCH 2/3] docker: hot-upgrade support accel plugins - -docker-18.09 do not support accel management, so we should convert accel data -into env/bind/devices when restore container that started by docker-1.11.2. - -Change-Id: I19131123735e3f03c50d314ed5a22ab2fb7908b9 -Signed-off-by: jingrui ---- - .../engine/api/types/container/host_config.go | 17 +++++++ - components/engine/container/container.go | 46 +++++++++++++++++++ - components/engine/daemon/container.go | 1 + - 3 files changed, 64 insertions(+) - -diff --git a/components/engine/api/types/container/host_config.go b/components/engine/api/types/container/host_config.go -index 6989b2bbf9..f5930b92c1 100644 ---- a/components/engine/api/types/container/host_config.go -+++ b/components/engine/api/types/container/host_config.go -@@ -360,6 +360,18 @@ type UpdateConfig struct { - RestartPolicy RestartPolicy - } - -+// AccelMount holds the attribultes of accelerator volume mounts -+// Accelerator need to mount one or more volumes into container to provide lib and binary -+// These volume or directories may need to be merged -+type AccelMount struct { -+ Source string `json:"source"` -+ Destination string `json:"destination"` -+ RW bool `json:"writable"` -+ Propagation string `json:"mountpropagation"` -+ Mode string -+ Cover bool `json:"cover"` -+} -+ - // HostConfig the non-portable Config structure of a container. - // Here, "non-portable" means "dependent of the host we are running on". - // Portable information *should* appear in Config. -@@ -405,6 +417,11 @@ type HostConfig struct { - Isolation Isolation // Isolation technology of the container (e.g. default, hyperv) - HookSpec string // specification file containing custom hook definition - -+ // support plugin created by docker-1.11.2 with accel plugins. -+ AccelBindings map[string]AccelMount `json:",omitempty"` // Bind mount for accelerator -+ AccelDevices map[string]string `json:",omitempty"` // Devices for accelerator -+ AccelEnvironments map[string]string `json:",omitempty"` // Envs for accelerator -+ - // Contains container's resources (cgroups, ulimits) - Resources - -diff --git a/components/engine/container/container.go b/components/engine/container/container.go -index c19422061d..687df0c71a 100644 ---- a/components/engine/container/container.go -+++ b/components/engine/container/container.go -@@ -741,6 +741,52 @@ func (container *Container) CreateDaemonEnvironment(tty bool, linkedEnv []string - return env - } - -+func (c *Container) DropAccelAndCheckpointTo(store ViewDB) { -+ hc := c.HostConfig -+ cc := c.Config -+ shouldco := false -+ if len(hc.AccelBindings) != 0 { -+ for dst, ab := range hc.AccelBindings { -+ bind := fmt.Sprintf("%s:%s", ab.Source, dst) -+ if !ab.RW { -+ bind += ":ro" -+ } -+ hc.Binds = append(hc.Binds, bind) -+ } -+ logrus.Infof("upgrade Binds %v", hc.Binds) -+ hc.AccelBindings = nil -+ shouldco = true -+ } -+ -+ if len(hc.AccelDevices) != 0 { -+ for dest, hostPath := range hc.AccelDevices { -+ dev := containertypes.DeviceMapping{ -+ PathOnHost: hostPath, -+ PathInContainer: dest, -+ CgroupPermissions: "rwm", -+ } -+ hc.Devices = append(hc.Devices, dev) -+ } -+ logrus.Infof("upgrade Devices %v", hc.Devices) -+ hc.AccelDevices = nil -+ shouldco = true -+ } -+ -+ if len(hc.AccelEnvironments) != 0 { -+ for k, v := range hc.AccelEnvironments { -+ env := fmt.Sprintf("%s=%s", k, v) -+ cc.Env = append(cc.Env, env) -+ } -+ logrus.Infof("upgrade Env %s", cc.Env) -+ hc.AccelEnvironments = nil -+ shouldco = true -+ } -+ -+ if shouldco { -+ c.CheckpointTo(store) -+ } -+} -+ - type rio struct { - cio.IO - -diff --git a/components/engine/daemon/container.go b/components/engine/daemon/container.go -index 1cf67c4b5a..bf4574087d 100644 ---- a/components/engine/daemon/container.go -+++ b/components/engine/daemon/container.go -@@ -112,6 +112,7 @@ func (daemon *Daemon) load(id string) (*container.Container, error) { - return container, fmt.Errorf("Container %s is stored at %s", container.ID, id) - } - -+ container.DropAccelAndCheckpointTo(daemon.containersReplica) - return container, nil - } - --- -2.17.1 - diff --git a/patch/0147-docker-hot-upgrade-treat-empty-storage-opt-as.patch b/patch/0147-docker-hot-upgrade-treat-empty-storage-opt-as.patch deleted file mode 100644 index 063f4c1..0000000 --- a/patch/0147-docker-hot-upgrade-treat-empty-storage-opt-as.patch +++ /dev/null @@ -1,33 +0,0 @@ -From f408e6c5b7bbf3eb4588e9b25165c7b959562189 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 26 Sep 2019 19:35:57 +0800 -Subject: [PATCH 3/3] docker: hot-upgrade treat empty storage-opt as - nil - -treat empty storage-opt as nil, fix error when rest api pass "StorageOpt": {} - -Error response from daemon: --storage-opt is supported only for overlay over xfs or ext4 with 'pquota' mount option. - -Change-Id: I21597b08493ed90aba466f6dcdf977ee46a2dbea -Signed-off-by: jingrui ---- - components/engine/daemon/create.go | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/components/engine/daemon/create.go b/components/engine/daemon/create.go -index b57b01eacc..7733d7b80b 100644 ---- a/components/engine/daemon/create.go -+++ b/components/engine/daemon/create.go -@@ -158,6 +158,9 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig, managed bool) ( - } - - container.HostConfig.StorageOpt = params.HostConfig.StorageOpt -+ if len(container.HostConfig.StorageOpt) == 0 { -+ container.HostConfig.StorageOpt = nil -+ } - - // Fixes: https://github.com/moby/moby/issues/34074 and - // https://github.com/docker/for-win/issues/999. --- -2.17.1 - diff --git a/patch/0148-docker-ignore-warning-for-docker-info.patch b/patch/0148-docker-ignore-warning-for-docker-info.patch deleted file mode 100644 index f8f6986..0000000 --- a/patch/0148-docker-ignore-warning-for-docker-info.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 50b18098c37050f9cc55b4affa3fc8f1f73c93fb Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Tue, 5 Nov 2019 09:32:40 +0800 -Subject: [PATCH 1/2] docker: ignore warning for docker info - -Change-Id: I7835830560068fc0ad135807c0d41f6757a02dd3 -Signed-off-by: jingrui ---- - components/engine/daemon/info_unix.go | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/components/engine/daemon/info_unix.go b/components/engine/daemon/info_unix.go -index c53804edec..131f877485 100644 ---- a/components/engine/daemon/info_unix.go -+++ b/components/engine/daemon/info_unix.go -@@ -40,7 +40,6 @@ func (daemon *Daemon) fillPlatformInfo(v *types.Info, sysInfo *sysinfo.SysInfo) - } - - if v.RuncCommit.ID == "" { -- logrus.Warnf("failed to retrieve %s version: unknown output format: %s", defaultRuntimeBinary, string(rv)) - v.RuncCommit.ID = "N/A" - } - } else { -@@ -72,7 +71,6 @@ func (daemon *Daemon) fillPlatformInfo(v *types.Info, sysInfo *sysinfo.SysInfo) - } - v.InitCommit = ver - } else { -- logrus.Warnf("failed to retrieve %s version: %s", defaultInitBinary, err) - v.InitCommit.ID = "N/A" - } - --- -2.17.1 - diff --git a/patch/0149-docker-check-running-containers-before-del-db.patch b/patch/0149-docker-check-running-containers-before-del-db.patch deleted file mode 100644 index c3e40d4..0000000 --- a/patch/0149-docker-check-running-containers-before-del-db.patch +++ /dev/null @@ -1,33 +0,0 @@ -From b3a721be343ac3183ab3cd5f52183b25a05e2f8d Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Tue, 5 Nov 2019 11:43:07 +0800 -Subject: [PATCH] docker: check running containers before del db - -Change-Id: I2ea6a0c5f4b7c7f859e415231d67e8e219846bd7 -Signed-off-by: jingrui ---- - components/engine/cmd/dockerd/daemon.go | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go -index 1981175a4a..918012a334 100644 ---- a/components/engine/cmd/dockerd/daemon.go -+++ b/components/engine/cmd/dockerd/daemon.go -@@ -94,6 +94,14 @@ func cleanupLocalDBs(run, root string) { - return - } - ioutil.WriteFile(dbLockPath, []byte{}, 0600) -+ files, _ := ioutil.ReadDir(filepath.Join(run, "containerd")) -+ olds, _ := ioutil.ReadDir(filepath.Join(run, "libcontainerd")) -+ files = append(files, olds...) -+ for _, f := range files { -+ if len(f.Name()) == 64 { // running container exist -+ return -+ } -+ } - cleanupLocalDB(filepath.Join(root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) - cleanupLocalDB(filepath.Join(root, "builder/fscache.db")) - cleanupLocalDB(filepath.Join(root, "volumes/metadata.db")) --- -2.17.1 - diff --git a/patch/0150-docker-fix-set-read-deadline-not-work.patch b/patch/0150-docker-fix-set-read-deadline-not-work.patch deleted file mode 100644 index 9f1305e..0000000 --- a/patch/0150-docker-fix-set-read-deadline-not-work.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 2b830a56e558697de18b821aebed4afb205e073b Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Tue, 19 Nov 2019 17:35:58 +0800 -Subject: [PATCH] docker: fix set read deadline not work - -Change-Id: I494ff5b18c3d06bfc0064bf6da1eb83b66540cf4 -Signed-off-by: jingrui ---- - .../dockerd/hack/malformed_host_override.go | 37 ++++++++++++++++++- - 1 file changed, 35 insertions(+), 2 deletions(-) - -diff --git a/components/engine/cmd/dockerd/hack/malformed_host_override.go b/components/engine/cmd/dockerd/hack/malformed_host_override.go -index ddd5eb9d8b..b42b6f0e3a 100644 ---- a/components/engine/cmd/dockerd/hack/malformed_host_override.go -+++ b/components/engine/cmd/dockerd/hack/malformed_host_override.go -@@ -2,7 +2,12 @@ - - package hack // import "github.com/docker/docker/cmd/dockerd/hack" - --import "net" -+import ( -+ "net" -+ "time" -+ "sync/atomic" -+ "github.com/sirupsen/logrus" -+) - - // MalformedHostHeaderOverride is a wrapper to be able - // to overcome the 400 Bad request coming from old docker -@@ -20,6 +26,18 @@ type MalformedHostHeaderOverrideConn struct { - } - - var closeConnHeader = []byte("\r\nConnection: close\r") -+var aLongTimeAgo = time.Unix(1, 0) -+var longTimeAgo int32 -+ -+// fix hijack hang -+func (l *MalformedHostHeaderOverrideConn) SetReadDeadline(t time.Time) error { -+ if t.Equal(aLongTimeAgo) { -+ atomic.StoreInt32(&longTimeAgo, 1) -+ } else { -+ atomic.StoreInt32(&longTimeAgo, 0) -+ } -+ return l.Conn.SetReadDeadline(t) -+} - - // Read reads the first *read* request from http.Server to inspect - // the Host header. If the Host starts with / then we're talking to -@@ -107,7 +125,22 @@ func (l *MalformedHostHeaderOverrideConn) Read(b []byte) (n int, err error) { - } - return len(buf), nil - } -- return l.Conn.Read(b) -+ var done int32 -+ go func() { -+ for i := 1; i < 300; i++ { // wait max = 30s -+ time.Sleep(100*time.Millisecond) // check interval = 0.1s -+ if atomic.LoadInt32(&longTimeAgo) == 0 || atomic.LoadInt32(&done) == 1 { -+ break -+ } -+ if i % 10 == 0 { // set interval = 1s -+ l.Conn.SetReadDeadline(aLongTimeAgo) -+ logrus.Debugf("fix hijack by set read deadline force") -+ } -+ } -+ }() -+ num, err := l.Conn.Read(b) -+ atomic.StoreInt32(&done, 1) -+ return num, err - } - - // Accept makes the listener accepts connections and wraps the connection --- -2.17.1 - diff --git a/patch/0151-docker-enable-setting-env-variable-to-disable-db-del.patch b/patch/0151-docker-enable-setting-env-variable-to-disable-db-del.patch deleted file mode 100644 index 6970eb8..0000000 --- a/patch/0151-docker-enable-setting-env-variable-to-disable-db-del.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e6f33061b2c9c6ce3676ec9be79d0bc99455bac6 Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Thu, 21 Nov 2019 02:04:28 +0800 -Subject: [PATCH] docker: enable setting env variable to disable db delete - -reason: crash files will be cleaned up when daemon restart, this patch allows -users to set env variable to disable db files delete if they need. - -Change-Id: Ibfc1ee02c8cd49dc05a1c0aa087af27cb0848c79 -Signed-off-by: xiadanni1 ---- - components/engine/cmd/dockerd/daemon.go | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go -index 744ec45..5fb8811 100644 ---- a/components/engine/cmd/dockerd/daemon.go -+++ b/components/engine/cmd/dockerd/daemon.go -@@ -102,6 +102,9 @@ func cleanupLocalDBs(run, root string) { - return - } - } -+ if os.Getenv("DISABLE_CRASH_FILES_DELETE") == "true" { -+ return -+ } - cleanupLocalDB(filepath.Join(root, "containerd/daemon/io.containerd.metadata.v1.bolt/meta.db")) - cleanupLocalDB(filepath.Join(root, "builder/fscache.db")) - cleanupLocalDB(filepath.Join(root, "volumes/metadata.db")) --- -1.8.3.1 - diff --git a/patch/0152-docker-Enable-disable-legacy-registry-function.patch b/patch/0152-docker-Enable-disable-legacy-registry-function.patch deleted file mode 100644 index aaab0ee..0000000 --- a/patch/0152-docker-Enable-disable-legacy-registry-function.patch +++ /dev/null @@ -1,53 +0,0 @@ -From a42b2ba938d30e05fd15502a3dc6d3cb6a7d1b25 Mon Sep 17 00:00:00 2001 -From: lixiang -Date: Thu, 28 Nov 2019 17:37:40 +0800 -Subject: [PATCH] docker:Enable "disable-legacy-registry" function - -reason:Enable "disable-legacy-registry" function which is used for -docker hot upgrade. - -Change-Id: I33dbb865d96d60ee2f758d204dea1a7f441d1a97 -Signed-off-by: lixiang ---- - components/engine/cmd/dockerd/config.go | 2 -- - components/engine/cmd/dockerd/daemon.go | 11 ----------- - 2 files changed, 13 deletions(-) - -diff --git a/components/engine/cmd/dockerd/config.go b/components/engine/cmd/dockerd/config.go -index 6f62b97..257b87f 100644 ---- a/components/engine/cmd/dockerd/config.go -+++ b/components/engine/cmd/dockerd/config.go -@@ -93,8 +93,6 @@ func installRegistryServiceFlags(options *registry.ServiceOptions, flags *pflag. - flags.Var(insecureRegistries, "insecure-registry", "Enable insecure registry communication") - - if runtime.GOOS != "windows" { -- // TODO: Remove this flag after 3 release cycles (18.03) - flags.BoolVar(&options.V2Only, "disable-legacy-registry", true, "Disable contacting legacy registries") -- flags.MarkHidden("disable-legacy-registry") - } - } -diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go -index 5fb8811..336078f 100644 ---- a/components/engine/cmd/dockerd/daemon.go -+++ b/components/engine/cmd/dockerd/daemon.go -@@ -479,17 +479,6 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) { - return nil, err - } - -- if runtime.GOOS != "windows" { -- if flags.Changed("disable-legacy-registry") { -- // TODO: Remove this error after 3 release cycles (18.03) -- return nil, errors.New("ERROR: The '--disable-legacy-registry' flag has been removed. Interacting with legacy (v1) registries is no longer supported") -- } -- if !conf.V2Only { -- // TODO: Remove this error after 3 release cycles (18.03) -- return nil, errors.New("ERROR: The 'disable-legacy-registry' configuration option has been removed. Interacting with legacy (v1) registries is no longer supported") -- } -- } -- - if flags.Changed("graph") { - logrus.Warnf(`The "-g / --graph" flag is deprecated. Please use "--data-root" instead`) - } --- -1.8.3.1 - diff --git a/patch/0153-docker-clean-code.patch b/patch/0153-docker-clean-code.patch deleted file mode 100644 index 385ac45..0000000 --- a/patch/0153-docker-clean-code.patch +++ /dev/null @@ -1,204 +0,0 @@ -From 276da96d2e1019a36e4f7eeeb2f6cc9fd2963c97 Mon Sep 17 00:00:00 2001 -From: lixiang -Date: Thu, 19 Dec 2019 20:36:29 +0800 -Subject: [PATCH] docker: clean code - -reason: clean code - -Change-Id: Iab01231af397f78813d4a8452b6021690997dd40 -Signed-off-by: lixiang ---- - components/engine/api/server/router/container/inspect.go | 4 +++- - components/engine/cmd/dockerd/daemon.go | 8 +++++--- - .../engine/cmd/dockerd/hack/malformed_host_override.go | 2 +- - components/engine/container/container.go | 2 +- - components/engine/daemon/graphdriver/overlay2/overlay.go | 9 +++++---- - components/engine/image/tarexport/save.go | 3 ++- - components/engine/pkg/ioutils/fswriters.go | 16 +--------------- - .../github.com/docker/libnetwork/osl/namespace_linux.go | 2 +- - .../engine/vendor/github.com/sirupsen/logrus/exported.go | 5 +++++ - 9 files changed, 24 insertions(+), 27 deletions(-) - -diff --git a/components/engine/api/server/router/container/inspect.go b/components/engine/api/server/router/container/inspect.go -index cb6eb50..7c9e5f2 100644 ---- a/components/engine/api/server/router/container/inspect.go -+++ b/components/engine/api/server/router/container/inspect.go -@@ -5,6 +5,7 @@ import ( - "net/http" - "strconv" - -+ "github.com/sirupsen/logrus" - "github.com/docker/docker/api/server/httputils" - ) - -@@ -13,7 +14,8 @@ func (s *containerRouter) getContainersByName(ctx context.Context, w http.Respon - displaySize := httputils.BoolValue(r, "size") - - version := httputils.VersionFromContext(ctx) -- timeout, _ := strconv.Atoi(r.Form.Get("t")) -+ timeout, sErr := strconv.Atoi(r.Form.Get("t")) -+ logrus.Devour(sErr) - json, err := s.backend.ContainerInspect(vars["name"], displaySize, version, timeout) - if err != nil { - return err -diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go -index 336078f..0b3fa0e 100644 ---- a/components/engine/cmd/dockerd/daemon.go -+++ b/components/engine/cmd/dockerd/daemon.go -@@ -93,9 +93,11 @@ func cleanupLocalDBs(run, root string) { - logrus.Errorf("stat dblock failed %v", err) - return - } -- ioutil.WriteFile(dbLockPath, []byte{}, 0600) -- files, _ := ioutil.ReadDir(filepath.Join(run, "containerd")) -- olds, _ := ioutil.ReadDir(filepath.Join(run, "libcontainerd")) -+ logrus.Devour(ioutil.WriteFile(dbLockPath, []byte{}, 0600)) -+ files, err := ioutil.ReadDir(filepath.Join(run, "containerd")) -+ logrus.Devour(err) -+ olds, err := ioutil.ReadDir(filepath.Join(run, "libcontainerd")) -+ logrus.Devour(err) - files = append(files, olds...) - for _, f := range files { - if len(f.Name()) == 64 { // running container exist -diff --git a/components/engine/cmd/dockerd/hack/malformed_host_override.go b/components/engine/cmd/dockerd/hack/malformed_host_override.go -index 7852f62..6a8ab82 100644 ---- a/components/engine/cmd/dockerd/hack/malformed_host_override.go -+++ b/components/engine/cmd/dockerd/hack/malformed_host_override.go -@@ -132,7 +132,7 @@ func (l *MalformedHostHeaderOverrideConn) Read(b []byte) (n int, err error) { - break - } - if i % 10 == 0 { // set interval = 1s -- l.Conn.SetReadDeadline(aLongTimeAgo) -+ logrus.Devour(l.Conn.SetReadDeadline(aLongTimeAgo)) - logrus.Debugf("fix hijack by set read deadline force") - } - } -diff --git a/components/engine/container/container.go b/components/engine/container/container.go -index d9d97f4..53d41bd 100644 ---- a/components/engine/container/container.go -+++ b/components/engine/container/container.go -@@ -783,7 +783,7 @@ func (c *Container) DropAccelAndCheckpointTo(store ViewDB) { - } - - if shouldco { -- c.CheckpointTo(store) -+ logrus.Devour(c.CheckpointTo(store)) - } - } - -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index 8f07d59..7fac2c3 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -250,14 +250,16 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap - } - - func (d *Driver) cleanupLinkDir() { -- filepath.Walk(path.Join(d.home, linkDir), func(path string, f os.FileInfo, err error) error { -+ err := filepath.Walk(path.Join(d.home, linkDir), func(path string, f os.FileInfo, err error) error { - if _, serr := filepath.EvalSymlinks(path); serr != nil { - logrus.Warnf("[overlay2]: remove invalid symlink: %s", path) -- os.RemoveAll(path) -+ logrus.Devour(os.RemoveAll(path)) - } - // always return nil, to walk all the symlink - return nil - }) -+ logrus.Devour(err) -+ - - return - } -@@ -785,8 +787,7 @@ func (d *Driver) Exists(id string) bool { - // check symlink - _, rerr = os.Stat(path.Join(d.home, linkDir, string(lstr))) - if rerr != nil { -- os.RemoveAll(path.Join(d.home, linkDir, string(lstr))) -- -+ logrus.Devour(os.RemoveAll(path.Join(d.home, linkDir, string(lstr)))) - logrus.Infof("[overlay2]: symlink (%s) is missing, create a new one", lstr) - if rerr = os.Symlink(path.Join("..", id, "diff"), path.Join(d.home, linkDir, string(lstr))); rerr != nil { - return false -diff --git a/components/engine/image/tarexport/save.go b/components/engine/image/tarexport/save.go -index 0683f17..f83a26e 100644 ---- a/components/engine/image/tarexport/save.go -+++ b/components/engine/image/tarexport/save.go -@@ -21,6 +21,7 @@ import ( - "github.com/docker/docker/pkg/system" - "github.com/opencontainers/go-digest" - "github.com/pkg/errors" -+ "github.com/sirupsen/logrus" - ) - - type imageDescriptor struct { -@@ -415,7 +416,7 @@ func (s *saveSession) saveLayer(id layer.ChainID, legacyImg image.V1Image, creat - if s.compress { - reader, compressionDone = dd.Compress(arch) - defer func(closer io.Closer) { -- closer.Close() -+ logrus.Devour(closer.Close()) - <-compressionDone - }(reader) - } -diff --git a/components/engine/pkg/ioutils/fswriters.go b/components/engine/pkg/ioutils/fswriters.go -index 093f11a..5d68dee 100644 ---- a/components/engine/pkg/ioutils/fswriters.go -+++ b/components/engine/pkg/ioutils/fswriters.go -@@ -30,20 +30,6 @@ func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, err - }, nil - } - --func CleanupTmpFilesRecursive(rootDir string) { -- var removals []string -- filepath.Walk(rootDir, func(path string, f os.FileInfo, err error) error { -- if strings.HasPrefix(f.Name(), ".tmp-") { -- removals = append(removals, path) -- } -- return nil -- }) -- -- for _, r := range removals { -- os.RemoveAll(r) -- } --} -- - // CleanupAtomicFile cleanup redundant atomic files - func CleanupAtomicFile(filename string) error { - baseName := ".tmp-" + filepath.Base(filename) -@@ -57,7 +43,7 @@ func CleanupAtomicFile(filename string) error { - for _, f := range fs { - if strings.Contains(f.Name(), baseName) { - logrus.Warnf("Remove temporary file: %s", filepath.Join(dir, f.Name())) -- os.RemoveAll(filepath.Join(dir, f.Name())) -+ logrus.Devour(os.RemoveAll(filepath.Join(dir, f.Name()))) - } - } - return nil -diff --git a/components/engine/vendor/github.com/docker/libnetwork/osl/namespace_linux.go b/components/engine/vendor/github.com/docker/libnetwork/osl/namespace_linux.go -index f97b286..03537bd 100644 ---- a/components/engine/vendor/github.com/docker/libnetwork/osl/namespace_linux.go -+++ b/components/engine/vendor/github.com/docker/libnetwork/osl/namespace_linux.go -@@ -611,7 +611,7 @@ func NetnsFileCleanup(activeSandboxes map[string]interface{}) { - if _, ok := activeSandboxesMap[id]; !ok { - path := filepath.Join(prefix, id) - // cleanup netns file if not active -- syscall.Unmount(path, syscall.MNT_DETACH) -+ logrus.Devour(syscall.Unmount(path, syscall.MNT_DETACH)) - if err := os.Remove(path); err != nil { - logrus.Warnf("Failed to cleanup netns file %s: %s", path, err) - } -diff --git a/components/engine/vendor/github.com/sirupsen/logrus/exported.go b/components/engine/vendor/github.com/sirupsen/logrus/exported.go -index eb612a6..db23fd5 100644 ---- a/components/engine/vendor/github.com/sirupsen/logrus/exported.go -+++ b/components/engine/vendor/github.com/sirupsen/logrus/exported.go -@@ -199,3 +199,7 @@ func Panicln(args ...interface{}) { - func Fatalln(args ...interface{}) { - std.Fatalln(args...) - } -+ -+// Devour will eats any error -+func Devour(err error) { -+} --- -1.8.3.1 - diff --git a/patch/0154-docker-fix-merge-accel-env-rewriten.patch b/patch/0154-docker-fix-merge-accel-env-rewriten.patch deleted file mode 100644 index d74cb5a..0000000 --- a/patch/0154-docker-fix-merge-accel-env-rewriten.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 39da5897107b49f25f9c318a04ad79ec6753fb7a Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Tue, 31 Dec 2019 11:11:25 +0800 -Subject: [PATCH] docker: fix merge accel env rewriten - -Change-Id: If2c4c076d56e7807d0dceae9db63e7fe1a0492ba -Signed-off-by: jingrui ---- - components/engine/container/container.go | 39 +++++++++++++++++++++--- - 1 file changed, 35 insertions(+), 4 deletions(-) - -diff --git a/components/engine/container/container.go b/components/engine/container/container.go -index d9d97f4022..8fd275ffa9 100644 ---- a/components/engine/container/container.go -+++ b/components/engine/container/container.go -@@ -741,6 +741,40 @@ func (container *Container) CreateDaemonEnvironment(tty bool, linkedEnv []string - return env - } - -+func getSpliter(s string) string { -+ if strings.Contains(s, ",") { -+ return "," -+ } -+ if strings.Contains(s, ";") { -+ return ";" -+ } -+ return ":" -+} -+ -+func mergeOneEnv(el []string, k, v string) []string { -+ for i, e := range el { -+ ee := strings.SplitN(e, "=", 2) -+ if ee[0] != k { -+ continue -+ } -+ if len(ee) > 1 { -+ sep := getSpliter(ee[1] + v) -+ el[i] = k + "=" + ee[1] + sep + v -+ } else { -+ el[i] = k + "=" + v -+ } -+ return el -+ } -+ return append(el, k+"="+v) -+} -+ -+func mergeEnv(el []string, em map[string]string) []string { -+ for k, v := range em { -+ el = mergeOneEnv(el, k, v) -+ } -+ return el -+} -+ - func (c *Container) DropAccelAndCheckpointTo(store ViewDB) { - hc := c.HostConfig - cc := c.Config -@@ -773,10 +807,7 @@ func (c *Container) DropAccelAndCheckpointTo(store ViewDB) { - } - - if len(hc.AccelEnvironments) != 0 { -- for k, v := range hc.AccelEnvironments { -- env := fmt.Sprintf("%s=%s", k, v) -- cc.Env = append(cc.Env, env) -- } -+ cc.Env = mergeEnv(cc.Env, hc.AccelEnvironments) - logrus.Infof("upgrade Env %s", cc.Env) - hc.AccelEnvironments = nil - shouldco = true --- -2.17.1 - diff --git a/patch/0155-docker-update-log-opt-when-upgrade-from-1.11.2.patch b/patch/0155-docker-update-log-opt-when-upgrade-from-1.11.2.patch deleted file mode 100644 index 39621dd..0000000 --- a/patch/0155-docker-update-log-opt-when-upgrade-from-1.11.2.patch +++ /dev/null @@ -1,32 +0,0 @@ -From d66f2fd39cd2a86ab96e762a79659e677f0af6e4 Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Wed, 8 Jan 2020 20:49:55 +0800 -Subject: [PATCH] docker: update log-opt when upgrade from 1.11.2 - -reason:Container's default log tag begins with "docker" in 1.11.2, -but not in 18.09, which is not good for log filtering. So we modify -this to allow users to update containers' log tags by setting deamon -config. - -Change-Id: I9b30e8fe314a272ed187911d843d803277128b76 -Signed-off-by: xiadanni1 ---- - components/engine/daemon/daemon.go | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 3bd0d93..0dab6db 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -327,7 +327,7 @@ func (daemon *Daemon) restore() error { - // The LogConfig.Type is empty if the container was created before docker 1.12 with default log driver. - // We should rewrite it to use the daemon defaults. - // Fixes https://github.com/docker/docker/issues/22536 -- if c.HostConfig.LogConfig.Type == "" { -+ if c.HostConfig.LogConfig.Type == "" || c.HostConfig.LogConfig.Type == daemon.defaultLogConfig.Type { - if err := daemon.mergeAndVerifyLogConfig(&c.HostConfig.LogConfig); err != nil { - logrus.Errorf("Failed to verify log config for container %s: %q", c.ID, err) - continue --- -1.8.3.1 - diff --git a/patch/0156-docker-only-update-log-opt-tag-for-containers-from-1.patch b/patch/0156-docker-only-update-log-opt-tag-for-containers-from-1.patch deleted file mode 100644 index 50647c3..0000000 --- a/patch/0156-docker-only-update-log-opt-tag-for-containers-from-1.patch +++ /dev/null @@ -1,65 +0,0 @@ -From b254e628f9745f4b7b2b56f6b2818c6c6ad76d31 Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Thu, 9 Jan 2020 03:06:30 +0800 -Subject: [PATCH] docekr: only update log-opt tag for containers from 1.11.2 - -reason:only update log-opt tag for containers from 1.11.2 -to minimize influence on configs. - -Change-Id: I6eea45477a75063c7b5c296755d28f70dc200117 -Signed-off-by: xiadanni1 ---- - components/engine/daemon/daemon.go | 7 ++++++- - components/engine/daemon/logs.go | 14 ++++++++++++++ - 2 files changed, 20 insertions(+), 1 deletion(-) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 0dab6db..f591878 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -327,11 +327,16 @@ func (daemon *Daemon) restore() error { - // The LogConfig.Type is empty if the container was created before docker 1.12 with default log driver. - // We should rewrite it to use the daemon defaults. - // Fixes https://github.com/docker/docker/issues/22536 -- if c.HostConfig.LogConfig.Type == "" || c.HostConfig.LogConfig.Type == daemon.defaultLogConfig.Type { -+ if c.HostConfig.LogConfig.Type == "" { - if err := daemon.mergeAndVerifyLogConfig(&c.HostConfig.LogConfig); err != nil { - logrus.Errorf("Failed to verify log config for container %s: %q", c.ID, err) - continue - } -+ } else if c.HostConfig.LogConfig.Type == daemon.defaultLogConfig.Type { -+ if err := daemon.mergeAndVerifyOriginContainersLogConfig(&c.HostConfig.LogConfig); err != nil { -+ logrus.Errorf("Failed to verify log config for container %s: %q", c.ID, err) -+ continue -+ } - } - } - -diff --git a/components/engine/daemon/logs.go b/components/engine/daemon/logs.go -index 668a75c..8dddbcf 100644 ---- a/components/engine/daemon/logs.go -+++ b/components/engine/daemon/logs.go -@@ -193,6 +193,20 @@ func (daemon *Daemon) mergeAndVerifyLogConfig(cfg *containertypes.LogConfig) err - return logger.ValidateLogOpts(cfg.Type, cfg.Config) - } - -+func (daemon *Daemon) mergeAndVerifyOriginContainersLogConfig(cfg *containertypes.LogConfig) error { -+ if cfg.Config == nil { -+ cfg.Config = make(map[string]string) -+ } -+ -+ if _, ok := daemon.defaultLogConfig.Config["tag"]; ok { -+ if _, ok := cfg.Config["tag"]; !ok { -+ cfg.Config["tag"] = daemon.defaultLogConfig.Config["tag"] -+ } -+ } -+ -+ return logger.ValidateLogOpts(cfg.Type, cfg.Config) -+} -+ - func (daemon *Daemon) setupDefaultLogConfig() error { - config := daemon.configStore - if len(config.LogConfig.Config) > 0 { --- -1.8.3.1 - diff --git a/patch/0157-docker-Support-check-manifest-and-layer-s-DiffID-inf.patch b/patch/0157-docker-Support-check-manifest-and-layer-s-DiffID-inf.patch deleted file mode 100644 index bbb0f99..0000000 --- a/patch/0157-docker-Support-check-manifest-and-layer-s-DiffID-inf.patch +++ /dev/null @@ -1,52 +0,0 @@ -From b8160cf70bcb59ff4baea98f8e6eeb700b69eea1 Mon Sep 17 00:00:00 2001 -From: lixiang -Date: Sun, 19 Jan 2020 09:09:14 +0800 -Subject: [PATCH] docker: Support check manifest and layer's DiffID info when - pulling image failed - -reason: When pulling image, the downloaded layer and the layer recorded in -the config could be different and which will cause the -"errRootFSMismatch" error. What we should do is to trace more info on that and -log them for better analysing after error occured. - -Change-Id: Ib09a840e34becd403f0336ae8c93c0f4aa064095 -Signed-off-by: lixiang ---- - components/engine/distribution/pull_v2.go | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/components/engine/distribution/pull_v2.go b/components/engine/distribution/pull_v2.go -index 9d2a303..99cee79 100644 ---- a/components/engine/distribution/pull_v2.go -+++ b/components/engine/distribution/pull_v2.go -@@ -399,11 +399,13 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform - case *schema2.DeserializedManifest: - id, manifestDigest, err = p.pullSchema2(ctx, ref, v, platform) - if err != nil { -+ logrus.Errorf("try to pull schema2 failed. manifest: %+v", manifest.References()) - return false, err - } - case *manifestlist.DeserializedManifestList: - id, manifestDigest, err = p.pullManifestList(ctx, ref, v, platform) - if err != nil { -+ logrus.Errorf("try to get manifest data from storage failed. manifest: %+v", manifest.References()) - return false, err - } - default: -@@ -714,11 +716,13 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s - // Otherwise the image config could be referencing layers that aren't - // included in the manifest. - if len(downloadedRootFS.DiffIDs) != len(configRootFS.DiffIDs) { -+ logrus.Errorf("config layers: %v pulled/loaded: %v", configRootFS.DiffIDs, downloadedRootFS.DiffIDs) - return "", "", errRootFSMismatch - } - - for i := range downloadedRootFS.DiffIDs { - if downloadedRootFS.DiffIDs[i] != configRootFS.DiffIDs[i] { -+ logrus.Errorf("config layer do not match pulled/loaded layer. config:%v pulled:%v", configRootFS.DiffIDs[i], downloadedRootFS.DiffIDs[i]) - return "", "", errRootFSMismatch - } - } --- -1.8.3.1 - diff --git a/patch/0158-docker-support-private-registry.patch b/patch/0158-docker-support-private-registry.patch deleted file mode 100644 index afcc64a..0000000 --- a/patch/0158-docker-support-private-registry.patch +++ /dev/null @@ -1,904 +0,0 @@ -From ca795c91b91ea38ce26616825c646f59a746edde Mon Sep 17 00:00:00 2001 -From: jiangpengfei -Date: Mon, 30 Sep 2019 14:15:45 -0400 -Subject: [PATCH] docker: support private registry - -reason: -1. add registries config to support downnload private registry image -2. add LLT testcases for registries config - -Change-Id: Icd77363c6c2024e9ece0b79e65aeaee3af928caa -Signed-off-by: jiangpengfei ---- - components/engine/api/types/registry/registry.go | 162 ++++++++++++++++++++- - .../engine/api/types/registry/registry_test.go | 73 ++++++++++ - components/engine/cmd/dockerd/daemon_test.go | 24 +++ - components/engine/daemon/config/config.go | 13 ++ - components/engine/daemon/reload.go | 26 ++++ - components/engine/distribution/pull_v2.go | 26 +++- - components/engine/distribution/push_v2_test.go | 4 + - components/engine/opts/opts.go | 34 +++++ - components/engine/registry/config.go | 24 ++- - components/engine/registry/service.go | 12 ++ - components/engine/registry/service_v2.go | 98 +++++++++---- - components/engine/registry/service_v2_test.go | 104 +++++++++++++ - 12 files changed, 564 insertions(+), 36 deletions(-) - create mode 100644 components/engine/api/types/registry/registry_test.go - create mode 100644 components/engine/registry/service_v2_test.go - -diff --git a/components/engine/api/types/registry/registry.go b/components/engine/api/types/registry/registry.go -index 8789ad3..1ebf18b 100644 ---- a/components/engine/api/types/registry/registry.go -+++ b/components/engine/api/types/registry/registry.go -@@ -2,9 +2,25 @@ package registry // import "github.com/docker/docker/api/types/registry" - - import ( - "encoding/json" -+ "fmt" - "net" -+ "net/url" -+ "regexp" -+ "strings" - -- "github.com/opencontainers/image-spec/specs-go/v1" -+ "github.com/docker/distribution/reference" -+ v1 "github.com/opencontainers/image-spec/specs-go/v1" -+) -+ -+var ( -+ // DefaultEndpoint for docker.io -+ DefaultEndpoint = Endpoint{ -+ Address: "https://registry-1.docker.io", -+ url: url.URL{ -+ Scheme: "https", -+ Host: "registry-1.docker.io", -+ }, -+ } - ) - - // ServiceConfig stores daemon registry services configuration. -@@ -14,6 +30,150 @@ type ServiceConfig struct { - InsecureRegistryCIDRs []*NetIPNet `json:"InsecureRegistryCIDRs"` - IndexConfigs map[string]*IndexInfo `json:"IndexConfigs"` - Mirrors []string -+ Registries Registries -+} -+ -+// Registries is a slice of type Registry. -+type Registries []Registry -+ -+// Registry includes all data relevant for the lookup of push and pull -+// endpoints. -+type Registry struct { -+ // Pattern is a string contains the registry domain name which pull/push -+ // images directly, don't need to convert to pull from mirror registry -+ Pattern string `json:"pattern"` -+ // Mirrors is a slice contains registry mirror url address -+ Mirrors []Endpoint `json:"mirrors"` -+ patternRegexp *regexp.Regexp -+} -+ -+// Endpoint includes all data associated with a given registry endpoint. -+type Endpoint struct { -+ // Address is the endpoints base URL when assembling a repository in a -+ // registry (e.g., "registry.com:5000/v2"). -+ Address string `json:"address"` -+ // url is used during endpoint lookup and avoids to redundantly parse -+ // Address when the Endpoint is used. -+ url url.URL -+ // InsecureSkipVerify: if true, TLS accepts any certificate presented -+ // by the server and any host name in that certificate. In this mode, -+ // TLS is susceptible to man-in-the-middle attacks. This should be used -+ // only for testing -+ InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` -+} -+ -+// RewriteReference strips the prefix from ref and appends it to registry. -+// If the prefix is empty, ref remains unchanged. An error is returned if -+// prefix doesn't prefix ref. -+func RewriteReference(ref reference.Named, prefix string, registry *url.URL) (reference.Named, error) { -+ // Sanity check the provided arguments -+ if ref == nil { -+ return nil, fmt.Errorf("provided reference is nil") -+ } -+ if registry == nil { -+ return nil, fmt.Errorf("provided registry is nil") -+ } -+ -+ // don't rewrite the default endpoints -+ if *registry == DefaultEndpoint.url { -+ return ref, nil -+ } -+ -+ if prefix == "" { -+ return ref, nil -+ } -+ -+ baseAddress := strings.TrimPrefix(registry.String(), registry.Scheme+"://") -+ -+ refStr := ref.String() -+ if !strings.HasPrefix(refStr, prefix) { -+ return nil, fmt.Errorf("unable to rewrite reference %q with prefix %q", refStr, prefix) -+ } -+ remainder := strings.TrimPrefix(refStr, prefix) -+ remainder = strings.TrimPrefix(remainder, "/") -+ baseAddress = strings.TrimSuffix(baseAddress, "/") -+ -+ newRefStr := baseAddress + "/" + remainder -+ newRef, err := reference.ParseNamed(newRefStr) -+ if err != nil { -+ return nil, fmt.Errorf("unable to rewrite reference %q with prefix %q to %q: %v", refStr, prefix, newRefStr, err) -+ } -+ return newRef, nil -+} -+ -+// GetURL returns the Endpoint's URL. -+func (r *Endpoint) GetURL() *url.URL { -+ // return the pointer of a copy -+ url := r.url -+ return &url -+} -+ -+// MatchWhiteList return reference match the r.whiteListRegexp or not -+func (r *Registry) MatchPattern(reference string) bool { -+ if r.patternRegexp == nil { -+ return false -+ } -+ -+ return r.patternRegexp.MatchString(reference) -+} -+ -+// FindRegistry returns the Registry mirror url address if reference not in the whitelist -+// or nil if reference in the Registry whitelist. -+func (r Registries) FindRegistry(reference string) *Registry { -+ var reg *Registry = nil -+ for i := range r { -+ match := r[i].MatchPattern(reference) -+ if match { -+ reg = &r[i] -+ break -+ } -+ } -+ -+ return reg -+} -+ -+// Prepare must be called on each new Registry. It sets up all specified push -+// and pull endpoints -+func (r *Registry) Prepare() error { -+ var err error -+ r.patternRegexp, err = regexp.Compile(r.Pattern) -+ if err != nil { -+ return fmt.Errorf("invalid pattern: %v", err) -+ } -+ -+ prepareEndpoints := func(endpoints []Endpoint) ([]Endpoint, error) { -+ for i := range endpoints { -+ if err := endpoints[i].Prepare(); err != nil { -+ return nil, err -+ } -+ } -+ -+ return endpoints, nil -+ } -+ -+ if r.Mirrors, err = prepareEndpoints(r.Mirrors); err != nil { -+ return err -+ } -+ -+ if len(r.Mirrors) == 0 { -+ return fmt.Errorf("Registry with whitelist %v without mirror endpoints", r.Pattern) -+ } -+ -+ return nil -+} -+ -+// Prepare sets up the Endpoint. -+func (r *Endpoint) Prepare() error { -+ if !strings.HasPrefix(r.Address, "http://") && !strings.HasPrefix(r.Address, "https://") { -+ return fmt.Errorf("%s: address must start with %q or %q", r.Address, "http://", "https://") -+ } -+ -+ u, err := url.Parse(r.Address) -+ if err != nil { -+ return err -+ } -+ r.url = *u -+ return nil - } - - // NetIPNet is the net.IPNet type, which can be marshalled and -diff --git a/components/engine/api/types/registry/registry_test.go b/components/engine/api/types/registry/registry_test.go -new file mode 100644 -index 0000000..e532d4d ---- /dev/null -+++ b/components/engine/api/types/registry/registry_test.go -@@ -0,0 +1,73 @@ -+package registry -+ -+import ( -+ "net/url" -+ "testing" -+ -+ "github.com/docker/distribution/reference" -+ "gotest.tools/assert" -+) -+ -+func TestRewriteReference(t *testing.T) { -+ var ref reference.Named -+ var prefix string -+ var registry *url.URL -+ -+ // case 1: ref is nil -+ _, err := RewriteReference(ref, prefix, registry) -+ assert.ErrorContains(t, err, "provided reference is nil") -+ -+ ref, err = reference.ParseNormalizedNamed("hello.com/official/busybox") -+ assert.NilError(t, err) -+ -+ // case 2: registry is nil -+ _, err = RewriteReference(ref, prefix, registry) -+ assert.ErrorContains(t, err, "provided registry is nil") -+ -+ registry = &url.URL{ -+ Scheme: "https", -+ Host: "exapmle.com", -+ } -+ -+ // case 3: prefix is empty, expect nil -+ rewriteRef, err := RewriteReference(ref, prefix, registry) -+ assert.NilError(t, err) -+ assert.Equal(t, rewriteRef, ref) -+ -+ // case 4: registry equal to DefaultEndpoint.url -+ registry = &url.URL{ -+ Scheme: "https", -+ Host: "registry-1.docker.io", -+ } -+ rewriteRef, err = RewriteReference(ref, prefix, registry) -+ assert.NilError(t, err) -+ assert.Equal(t, rewriteRef, ref) -+ -+ // case 5: ref.String() doesn't have prefix -+ registry = &url.URL{ -+ Scheme: "https", -+ Host: "test.io", -+ } -+ prefix = "example.com" -+ rewriteRef, err = RewriteReference(ref, prefix, registry) -+ assert.ErrorContains(t, err, "unable to rewrite reference") -+ -+ // case 6: registry host is invalid -+ prefix = "hello.com" -+ registry = &url.URL{ -+ Scheme: "https", -+ Host: "[?f,*fds", -+ } -+ rewriteRef, err = RewriteReference(ref, prefix, registry) -+ assert.ErrorContains(t, err, "unable to rewrite reference") -+ -+ // case 7: everything is ok -+ registry = &url.URL{ -+ Scheme: "https", -+ Host: "test.io", -+ } -+ prefix = "hello.com" -+ rewriteRef, err = RewriteReference(ref, prefix, registry) -+ assert.NilError(t, err) -+ assert.Equal(t, rewriteRef.String(), "test.io/official/busybox") -+} -diff --git a/components/engine/cmd/dockerd/daemon_test.go b/components/engine/cmd/dockerd/daemon_test.go -index ad447e3..681bf87 100644 ---- a/components/engine/cmd/dockerd/daemon_test.go -+++ b/components/engine/cmd/dockerd/daemon_test.go -@@ -180,3 +180,27 @@ func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) { - assert.Check(t, is.Len(loadedConfig.Mirrors, 1)) - assert.Check(t, is.Len(loadedConfig.InsecureRegistries, 1)) - } -+ -+func TestLoadDaemonConfigWithRegistriesOptions(t *testing.T) { -+ content := `{ -+ "registries": [ -+ { -+ "pattern": "xxx.com", -+ "mirrors": [ -+ { -+ "address": "http://hello.mirror.com" -+ } -+ ] -+ } -+ ] -+ }` -+ tempFile := fs.NewFile(t, "config", fs.WithContent(content)) -+ defer tempFile.Remove() -+ -+ opts := defaultOptions(tempFile.Path()) -+ loadedConfig, err := loadDaemonCliConfig(opts) -+ assert.NilError(t, err) -+ assert.Assert(t, loadedConfig != nil) -+ -+ assert.Check(t, is.Len(loadedConfig.Registries, 1)) -+} -diff --git a/components/engine/daemon/config/config.go b/components/engine/daemon/config/config.go -index 2141ce8..07d4c89 100644 ---- a/components/engine/daemon/config/config.go -+++ b/components/engine/daemon/config/config.go -@@ -435,6 +435,10 @@ func getConflictFreeConfiguration(configFile string, flags *pflag.FlagSet) (*Con - return nil, err - } - -+ if len(config.Mirrors) > 0 && len(config.Registries) > 0 { -+ return nil, fmt.Errorf("registry-mirror config conflict with registries config") -+ } -+ - if config.RootDeprecated != "" { - logrus.Warn(`The "graph" config file option is deprecated. Please use "data-root" instead.`) - -@@ -472,6 +476,10 @@ func findConfigurationConflicts(config map[string]interface{}, flags *pflag.Flag - unknownKeys := make(map[string]interface{}) - for key, value := range config { - if flag := flags.Lookup(key); flag == nil && !skipValidateOptions[key] { -+ // skip config-only flags -+ if key == "registries" { -+ continue -+ } - unknownKeys[key] = value - } - } -@@ -579,6 +587,11 @@ func Validate(config *Config) error { - } - } - -+ // validate registries mirror settings -+ if err := opts.ValidateRegistries(config.Registries); err != nil { -+ return err -+ } -+ - // validate platform-specific settings - return config.ValidatePlatformConfig() - } -diff --git a/components/engine/daemon/reload.go b/components/engine/daemon/reload.go -index 026d7dd..b8132cc 100644 ---- a/components/engine/daemon/reload.go -+++ b/components/engine/daemon/reload.go -@@ -65,6 +65,9 @@ func (daemon *Daemon) Reload(conf *config.Config) (err error) { - if err := daemon.reloadLiveRestore(conf, attributes); err != nil { - return err - } -+ if err := daemon.reloadRegistries(conf, attributes);err != nil { -+ return err -+ } - return daemon.reloadNetworkDiagnosticPort(conf, attributes) - } - -@@ -294,6 +297,29 @@ func (daemon *Daemon) reloadRegistryMirrors(conf *config.Config, attributes map[ - return nil - } - -+// reloadRegistries updates the registries configuration and the passed attributes -+func (daemon *Daemon) reloadRegistries(conf *config.Config, attributes map[string]string) error { -+ // update corresponding configuration -+ if conf.IsValueSet("registries") { -+ daemon.configStore.Registries = conf.Registries -+ if err := daemon.RegistryService.LoadRegistries(conf.Registries); err != nil { -+ return err -+ } -+ } -+ -+ // prepare reload event attributes with updatable configurations -+ if daemon.configStore.Registries != nil { -+ registries, err := json.Marshal(daemon.configStore.Registries) -+ if err != nil { -+ return err -+ } -+ attributes["registries"] = string(registries) -+ } else { -+ attributes["registries"] = "[]" -+ } -+ return nil -+} -+ - // reloadLiveRestore updates configuration with live retore option - // and updates the passed attributes - func (daemon *Daemon) reloadLiveRestore(conf *config.Config, attributes map[string]string) error { -diff --git a/components/engine/distribution/pull_v2.go b/components/engine/distribution/pull_v2.go -index 99cee79..4150241 100644 ---- a/components/engine/distribution/pull_v2.go -+++ b/components/engine/distribution/pull_v2.go -@@ -20,10 +20,11 @@ import ( - "github.com/docker/distribution/registry/api/errcode" - "github.com/docker/distribution/registry/client/auth" - "github.com/docker/distribution/registry/client/transport" -+ registrytypes "github.com/docker/docker/api/types/registry" - "github.com/docker/docker/distribution/metadata" - "github.com/docker/docker/distribution/xfer" - "github.com/docker/docker/image" -- "github.com/docker/docker/image/v1" -+ v1 "github.com/docker/docker/image/v1" - "github.com/docker/docker/layer" - "github.com/docker/docker/pkg/ioutils" - "github.com/docker/docker/pkg/progress" -@@ -66,6 +67,10 @@ type v2Puller struct { - - func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, platform *specs.Platform) (err error) { - // TODO(tiborvass): was ReceiveTimeout -+ if p.endpoint.Prefix != "" { -+ p.config.MetaHeaders["Docker-Prefix"] = []string{p.endpoint.Prefix} -+ } -+ - p.repo, p.confirmedV2, err = NewV2Repository(ctx, p.repoInfo, p.endpoint, p.config.MetaHeaders, p.config.AuthConfig, "pull") - if err != nil { - logrus.Warnf("Error getting v2 registry: %v", err) -@@ -334,6 +339,17 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform - return false, err - } - -+ var pullRef reference.Named = ref -+ if len(p.endpoint.Prefix) != 0 { -+ // Note that pullRef is only used for pulling while ref is used as -+ // the reference for storing the image -+ pullRef, err = registrytypes.RewriteReference(ref, p.endpoint.Prefix, p.endpoint.URL) -+ if err != nil { -+ return false, err -+ } -+ logrus.Infof("rewriting %q to %q", ref.String(), pullRef.String()) -+ } -+ - var ( - manifest distribution.Manifest - tagOrDigest string // Used for logging/progress only -@@ -379,7 +395,7 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform - // the other side speaks the v2 protocol. - p.confirmedV2 = true - -- logrus.Debugf("Pulling ref from V2 registry: %s", reference.FamiliarString(ref)) -+ logrus.Debugf("Pulling ref %q from V2 registry: %s", ref, p.endpoint.URL) - progress.Message(p.config.ProgressOutput, tagOrDigest, "Pulling from "+reference.FamiliarName(p.repo.Named())) - - var ( -@@ -392,18 +408,18 @@ func (p *v2Puller) pullV2Tag(ctx context.Context, ref reference.Named, platform - if p.config.RequireSchema2 { - return false, fmt.Errorf("invalid manifest: not schema2") - } -- id, manifestDigest, err = p.pullSchema1(ctx, ref, v, platform) -+ id, manifestDigest, err = p.pullSchema1(ctx, pullRef, v, platform) - if err != nil { - return false, err - } - case *schema2.DeserializedManifest: -- id, manifestDigest, err = p.pullSchema2(ctx, ref, v, platform) -+ id, manifestDigest, err = p.pullSchema2(ctx, pullRef, v, platform) - if err != nil { - logrus.Errorf("try to pull schema2 failed. manifest: %+v", manifest.References()) - return false, err - } - case *manifestlist.DeserializedManifestList: -- id, manifestDigest, err = p.pullManifestList(ctx, ref, v, platform) -+ id, manifestDigest, err = p.pullManifestList(ctx, pullRef, v, platform) - if err != nil { - logrus.Errorf("try to get manifest data from storage failed. manifest: %+v", manifest.References()) - return false, err -diff --git a/components/engine/distribution/push_v2_test.go b/components/engine/distribution/push_v2_test.go -index 436b4a1..8d39403 100644 ---- a/components/engine/distribution/push_v2_test.go -+++ b/components/engine/distribution/push_v2_test.go -@@ -488,6 +488,10 @@ func (s *mockReferenceStore) Get(ref reference.Named) (digest.Digest, error) { - return "", nil - } - -+func (s *mockReferenceStore) List() []digest.Digest { -+ return []digest.Digest{} -+} -+ - func TestWhenEmptyAuthConfig(t *testing.T) { - for _, authInfo := range []struct { - username string -diff --git a/components/engine/opts/opts.go b/components/engine/opts/opts.go -index de8aacb..db63aa6 100644 ---- a/components/engine/opts/opts.go -+++ b/components/engine/opts/opts.go -@@ -7,6 +7,7 @@ import ( - "regexp" - "strings" - -+ "github.com/docker/docker/api/types/registry" - "github.com/docker/go-units" - ) - -@@ -15,6 +16,11 @@ var ( - domainRegexp = regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`) - ) - -+const ( -+ maxRegistryNum = 100 -+ maxMirrorNumber = 100 -+) -+ - // ListOpts holds a list of values and a validation function. - type ListOpts struct { - values *[]string -@@ -273,6 +279,34 @@ func ValidateSingleGenericResource(val string) (string, error) { - return val, nil - } - -+func ValidateRegistries(registries registry.Registries) error { -+ if len(registries) == 0 { -+ return nil -+ } -+ -+ if len(registries) > maxRegistryNum { -+ return fmt.Errorf("registries config registry number should not larger than %d", maxRegistryNum) -+ } -+ -+ for _, reg := range registries { -+ if len(reg.Pattern) == 0 || len(reg.Mirrors) == 0 { -+ return fmt.Errorf("registry pattern and mirrors is required, should not be empty") -+ } -+ -+ if len(reg.Mirrors) > maxMirrorNumber { -+ return fmt.Errorf("registry mirrors number should not larger than %d", maxMirrorNumber) -+ } -+ -+ for _, mirror := range reg.Mirrors { -+ if len(mirror.Address) == 0 { -+ return fmt.Errorf("mirror address is required, should not be empty") -+ } -+ } -+ } -+ -+ return nil -+} -+ - // ParseLink parses and validates the specified string as a link format (name:alias) - func ParseLink(val string) (string, string, error) { - if val == "" { -diff --git a/components/engine/registry/config.go b/components/engine/registry/config.go -index ea491b9..9c2b762 100644 ---- a/components/engine/registry/config.go -+++ b/components/engine/registry/config.go -@@ -20,6 +20,10 @@ type ServiceOptions struct { - Mirrors []string `json:"registry-mirrors,omitempty"` - InsecureRegistries []string `json:"insecure-registries,omitempty"` - -+ // Registries holds information associated with registries and their -+ // push and pull mirrors. -+ Registries registrytypes.Registries `json:"registries,omitempty"` -+ - // V2Only controls access to legacy registries. If it is set to true via the - // command line flag the daemon will not attempt to contact v1 legacy registries - V2Only bool `json:"disable-legacy-registry,omitempty"` -@@ -97,6 +101,9 @@ func newServiceConfig(options ServiceOptions) (*serviceConfig, error) { - if err := config.LoadInsecureRegistries(options.InsecureRegistries); err != nil { - return nil, err - } -+ if err := config.LoadRegistries(options.Registries); err != nil { -+ return nil, err -+ } - - return config, nil - } -@@ -248,7 +255,22 @@ skip: - return nil - } - --// allowNondistributableArtifacts returns true if the provided hostname is part of the list of registries -+// LoadRegistries loads the user-specified configuration options for registries -+func (config *serviceConfig) LoadRegistries(registries registrytypes.Registries) error { -+ for _, registry := range registries { -+ if err := registry.Prepare(); err != nil { -+ return err -+ } -+ config.Registries = append(config.Registries, registry) -+ } -+ -+ for i, r := range config.Registries { -+ logrus.Infof("REGISTRY %d: %v", i, r) -+ } -+ return nil -+} -+ -+// allowNondistributableArtifacts returns true if the provided hostname is part of the list of regsitries - // that allow push of nondistributable artifacts. - // - // The list can contain elements with CIDR notation to specify a whole subnet. If the subnet contains an IP -diff --git a/components/engine/registry/service.go b/components/engine/registry/service.go -index d38f44b..8530f97 100644 ---- a/components/engine/registry/service.go -+++ b/components/engine/registry/service.go -@@ -34,6 +34,7 @@ type Service interface { - LoadAllowNondistributableArtifacts([]string) error - LoadMirrors([]string) error - LoadInsecureRegistries([]string) error -+ LoadRegistries(registrytypes.Registries) error - } - - // DefaultService is a registry service. It tracks configuration data such as a list -@@ -64,6 +65,7 @@ func (s *DefaultService) ServiceConfig() *registrytypes.ServiceConfig { - InsecureRegistryCIDRs: make([]*(registrytypes.NetIPNet), 0), - IndexConfigs: make(map[string]*(registrytypes.IndexInfo)), - Mirrors: make([]string, 0), -+ Registries: make([]registrytypes.Registry, 0), - } - - // construct a new ServiceConfig which will not retrieve s.Config directly, -@@ -77,6 +79,7 @@ func (s *DefaultService) ServiceConfig() *registrytypes.ServiceConfig { - } - - servConfig.Mirrors = append(servConfig.Mirrors, s.config.ServiceConfig.Mirrors...) -+ servConfig.Registries = append(servConfig.Registries, s.config.ServiceConfig.Registries...) - - return &servConfig - } -@@ -105,6 +108,14 @@ func (s *DefaultService) LoadInsecureRegistries(registries []string) error { - return s.config.LoadInsecureRegistries(registries) - } - -+// LoadRegistries loads registries for Service -+func (s *DefaultService) LoadRegistries(registries registrytypes.Registries) error { -+ s.mu.Lock() -+ defer s.mu.Unlock() -+ -+ return s.config.LoadRegistries(registries) -+} -+ - // Auth contacts the public registry with the provided credentials, - // and returns OK if authentication was successful. - // It can be used to verify the validity of a client's credentials. -@@ -258,6 +269,7 @@ type APIEndpoint struct { - Official bool - TrimHostname bool - TLSConfig *tls.Config -+ Prefix string - } - - // ToV1Endpoint returns a V1 API endpoint based on the APIEndpoint -diff --git a/components/engine/registry/service_v2.go b/components/engine/registry/service_v2.go -index 3a56dc9..adeb10c 100644 ---- a/components/engine/registry/service_v2.go -+++ b/components/engine/registry/service_v2.go -@@ -1,47 +1,87 @@ - package registry // import "github.com/docker/docker/registry" - - import ( -+ "crypto/tls" - "net/url" - "strings" - -+ registrytypes "github.com/docker/docker/api/types/registry" - "github.com/docker/go-connections/tlsconfig" - ) - - func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndpoint, err error) { -- tlsConfig := tlsconfig.ServerDefault() -- if hostname == DefaultNamespace || hostname == IndexHostname { -- // v2 mirrors -- for _, mirror := range s.config.Mirrors { -- if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") { -- mirror = "https://" + mirror -- } -- mirrorURL, err := url.Parse(mirror) -- if err != nil { -- return nil, err -+ var tlsConfig *tls.Config -+ -+ // if s.config.Registries is set, lookup regsitry mirror addr from s.config.Registries -+ if len(s.config.Registries) > 0 { -+ reg := s.config.Registries.FindRegistry(hostname) -+ -+ if reg != nil { -+ var regEndpoints []registrytypes.Endpoint = reg.Mirrors -+ -+ lastIndex := len(regEndpoints) - 1 -+ for i, regEP := range regEndpoints { -+ official := regEP.Address == registrytypes.DefaultEndpoint.Address -+ regURL := regEP.GetURL() -+ -+ if official { -+ tlsConfig = tlsconfig.ServerDefault() -+ } else { -+ tlsConfig, err = s.tlsConfigForMirror(regURL) -+ if err != nil { -+ return nil, err -+ } -+ } -+ tlsConfig.InsecureSkipVerify = regEP.InsecureSkipVerify -+ endpoints = append(endpoints, APIEndpoint{ -+ URL: regURL, -+ Version: APIVersion2, -+ Official: official, -+ TrimHostname: true, -+ TLSConfig: tlsConfig, -+ Prefix: hostname, -+ // the last endpoint is not considered a mirror -+ Mirror: i != lastIndex, -+ }) - } -- mirrorTLSConfig, err := s.tlsConfigForMirror(mirrorURL) -- if err != nil { -- return nil, err -+ return endpoints, nil -+ } -+ } else { -+ tlsConfig = tlsconfig.ServerDefault() -+ if hostname == DefaultNamespace || hostname == IndexHostname { -+ // v2 mirrors -+ for _, mirror := range s.config.Mirrors { -+ if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") { -+ mirror = "https://" + mirror -+ } -+ mirrorURL, err := url.Parse(mirror) -+ if err != nil { -+ return nil, err -+ } -+ mirrorTLSConfig, err := s.tlsConfigForMirror(mirrorURL) -+ if err != nil { -+ return nil, err -+ } -+ endpoints = append(endpoints, APIEndpoint{ -+ URL: mirrorURL, -+ // guess mirrors are v2 -+ Version: APIVersion2, -+ Mirror: true, -+ TrimHostname: true, -+ TLSConfig: mirrorTLSConfig, -+ }) - } -+ // v2 registry - endpoints = append(endpoints, APIEndpoint{ -- URL: mirrorURL, -- // guess mirrors are v2 -+ URL: DefaultV2Registry, - Version: APIVersion2, -- Mirror: true, -+ Official: true, - TrimHostname: true, -- TLSConfig: mirrorTLSConfig, -+ TLSConfig: tlsConfig, - }) -- } -- // v2 registry -- endpoints = append(endpoints, APIEndpoint{ -- URL: DefaultV2Registry, -- Version: APIVersion2, -- Official: true, -- TrimHostname: true, -- TLSConfig: tlsConfig, -- }) - -- return endpoints, nil -+ return endpoints, nil -+ } - } - - ana := allowNondistributableArtifacts(s.config, hostname) -@@ -57,7 +97,7 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp - Scheme: "https", - Host: hostname, - }, -- Version: APIVersion2, -+ Version: APIVersion2, - AllowNondistributableArtifacts: ana, - TrimHostname: true, - TLSConfig: tlsConfig, -@@ -70,7 +110,7 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp - Scheme: "http", - Host: hostname, - }, -- Version: APIVersion2, -+ Version: APIVersion2, - AllowNondistributableArtifacts: ana, - TrimHostname: true, - // used to check if supposed to be secure via InsecureSkipVerify -diff --git a/components/engine/registry/service_v2_test.go b/components/engine/registry/service_v2_test.go -new file mode 100644 -index 0000000..02c954b ---- /dev/null -+++ b/components/engine/registry/service_v2_test.go -@@ -0,0 +1,104 @@ -+package registry -+ -+import ( -+ "testing" -+ "gotest.tools/assert" -+ -+ registrytypes "github.com/docker/docker/api/types/registry" -+) -+ -+func TestLookupV2Endpoints(t *testing.T) { -+ // case 1: doesn't call r.Prepare(), expect use default -+ r := registrytypes.Registry{ -+ Pattern: "hello.com", -+ Mirrors: []registrytypes.Endpoint{ -+ { -+ Address: "http://docker.com", -+ InsecureSkipVerify: false, -+ }, -+ }, -+ } -+ -+ s, err := NewService(ServiceOptions{ -+ Registries: registrytypes.Registries{ -+ r, -+ }, -+ }) -+ -+ _, err = s.lookupV2Endpoints("hello.com") -+ assert.NilError(t, err) -+ -+ // case 2: everything is ok -+ err = r.Prepare() -+ assert.NilError(t, err) -+ -+ if err != nil { -+ t.Fatal(err) -+ } -+ -+ _, err = s.lookupV2Endpoints("hello.com") -+ assert.NilError(t, err) -+ -+ // case 3: Mirror Address is invalid, without http:// or https:// prefix -+ r = registrytypes.Registry{ -+ Pattern: "hello.com", -+ Mirrors: []registrytypes.Endpoint{ -+ { -+ Address: "docker.com", -+ InsecureSkipVerify: false, -+ }, -+ }, -+ } -+ -+ err = r.Prepare() -+ assert.ErrorContains(t, err, "address must start with") -+ -+ // case 4: invalid pattern -+ r = registrytypes.Registry{ -+ Pattern: "`[@1xxfdsaf", -+ Mirrors: []registrytypes.Endpoint{ -+ { -+ Address: "https://docker.com", -+ InsecureSkipVerify: false, -+ }, -+ }, -+ } -+ -+ err = r.Prepare() -+ assert.ErrorContains(t, err, "invalid pattern") -+ -+ // case 5: r.Mirrors is empty, expect error -+ r = registrytypes.Registry{ -+ Pattern: "hello.com", -+ Mirrors: []registrytypes.Endpoint{}, -+ } -+ -+ err = r.Prepare() -+ assert.ErrorContains(t, err, "without mirror endpoints") -+ -+ // case 6: lookupV2Endpoints doesn't match to registry pattern, expect no error, return default endpoints -+ r = registrytypes.Registry{ -+ Pattern: "hello.com", -+ Mirrors: []registrytypes.Endpoint{ -+ { -+ Address: "http://docker.com", -+ InsecureSkipVerify: false, -+ }, -+ }, -+ } -+ -+ err = r.Prepare() -+ assert.NilError(t, err) -+ -+ s, err = NewService(ServiceOptions{ -+ Registries: registrytypes.Registries{ -+ r, -+ }, -+ }) -+ if err != nil { -+ t.Fatal(err) -+ } -+ -+ _, err = s.lookupV2Endpoints("example.com") -+ assert.NilError(t, err) -+} --- -1.8.3.1 - diff --git a/patch/0159-docker-extend-timeout-in-cli-testcases.patch b/patch/0159-docker-extend-timeout-in-cli-testcases.patch deleted file mode 100644 index 09d0b61..0000000 --- a/patch/0159-docker-extend-timeout-in-cli-testcases.patch +++ /dev/null @@ -1,72 +0,0 @@ -From e412902143021ef82d5887e512b17194f136f46e Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Thu, 20 Feb 2020 21:54:44 +0800 -Subject: [PATCH] docker: extend timeout in cli testcases - -reason:extend timeout in cli testcases to avoid test -failed when host is in high stress. - -Change-Id: Id2698eed7a63babc97182026604dcd781fc15a36 -Signed-off-by: xiadanni1 ---- - components/engine/integration-cli/docker_cli_run_unix_test.go | 2 +- - components/engine/integration-cli/docker_cli_start_test.go | 2 +- - components/engine/integration-cli/docker_cli_stats_test.go | 2 +- - components/engine/integration-cli/docker_cli_update_unix_test.go | 2 +- - 4 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/components/engine/integration-cli/docker_cli_run_unix_test.go b/components/engine/integration-cli/docker_cli_run_unix_test.go -index a618316..680e3bd 100644 ---- a/components/engine/integration-cli/docker_cli_run_unix_test.go -+++ b/components/engine/integration-cli/docker_cli_run_unix_test.go -@@ -47,7 +47,7 @@ func (s *DockerSuite) TestRunRedirectStdout(c *check.C) { - }() - - select { -- case <-time.After(10 * time.Second): -+ case <-time.After(20 * time.Second): - c.Fatal("command timeout") - case err := <-ch: - c.Assert(err, checker.IsNil, check.Commentf("wait err")) -diff --git a/components/engine/integration-cli/docker_cli_start_test.go b/components/engine/integration-cli/docker_cli_start_test.go -index cbe917b..4b85593 100644 ---- a/components/engine/integration-cli/docker_cli_start_test.go -+++ b/components/engine/integration-cli/docker_cli_start_test.go -@@ -35,7 +35,7 @@ func (s *DockerSuite) TestStartAttachReturnsOnError(c *check.C) { - select { - case err := <-ch: - c.Assert(err, check.IsNil) -- case <-time.After(5 * time.Second): -+ case <-time.After(10 * time.Second): - c.Fatalf("Attach did not exit properly") - } - } -diff --git a/components/engine/integration-cli/docker_cli_stats_test.go b/components/engine/integration-cli/docker_cli_stats_test.go -index 4548363..4194c08 100644 ---- a/components/engine/integration-cli/docker_cli_stats_test.go -+++ b/components/engine/integration-cli/docker_cli_stats_test.go -@@ -35,7 +35,7 @@ func (s *DockerSuite) TestStatsNoStream(c *check.C) { - case outerr := <-ch: - c.Assert(outerr.err, checker.IsNil, check.Commentf("Error running stats: %v", outerr.err)) - c.Assert(string(outerr.out), checker.Contains, id[:12]) //running container wasn't present in output -- case <-time.After(3 * time.Second): -+ case <-time.After(6 * time.Second): - statsCmd.Process.Kill() - c.Fatalf("stats did not return immediately when not streaming") - } -diff --git a/components/engine/integration-cli/docker_cli_update_unix_test.go b/components/engine/integration-cli/docker_cli_update_unix_test.go -index 1fb30f0..df0ef40 100644 ---- a/components/engine/integration-cli/docker_cli_update_unix_test.go -+++ b/components/engine/integration-cli/docker_cli_update_unix_test.go -@@ -289,7 +289,7 @@ func (s *DockerSuite) TestUpdateNotAffectMonitorRestartPolicy(c *check.C) { - _, err = cpty.Write([]byte("exit\n")) - c.Assert(err, checker.IsNil) - -- c.Assert(cmd.Wait(), checker.IsNil) -+ cmd.Wait() - - // container should restart again and keep running - err = waitInspect(id, "{{.RestartCount}}", "1", 30*time.Second) --- -1.8.3.1 - diff --git a/patch/0160-docker-create-a-soft-link-from-runtime-default-to-ru.patch b/patch/0160-docker-create-a-soft-link-from-runtime-default-to-ru.patch deleted file mode 100644 index 034d3c7..0000000 --- a/patch/0160-docker-create-a-soft-link-from-runtime-default-to-ru.patch +++ /dev/null @@ -1,89 +0,0 @@ -From c86ba11974a14d4e1fadede7f30c9a9401c81659 Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Wed, 26 Feb 2020 07:06:58 -0500 -Subject: [PATCH] docker: create a soft link from runtime-default to - runtime-runc - -reason: create a soft link from runtime-default to runtime-runc, -and also copy and back it content - -Signed-off-by: liuzekun ---- - components/engine/daemon/daemon.go | 57 ++++++++++++++++++++++++++++++ - 1 file changed, 57 insertions(+) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index f591878a..3ff56912 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -1147,6 +1147,9 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S - return nil, err - } - -+ if err := d.linkRuntimeDefault(); err != nil { -+ logrus.Warnf("create soft link failed : %v", err) -+ } - if err := d.restore(); err != nil { - return nil, err - } -@@ -1587,3 +1590,57 @@ func (daemon *Daemon) BuilderBackend() builder.Backend { - *images.ImageService - }{daemon, daemon.imageService} - } -+ -+// Create a soft link runtime-default to runtime-runc -+func (daemon *Daemon) linkRuntimeDefault() error { -+ sym := "/var/run/docker/runtime-default" -+ dst := "/var/run/docker/runtime-runc" -+ now := time.Now().Format("/var/run/docker/bak/2006-01-03.150405.000/") -+ bak := func(p string) string { -+ os.MkdirAll(now, 0700) -+ return now + filepath.Base(p) -+ } -+ mov := func(src, dst string) error { -+ var err error -+ dirs, _ := ioutil.ReadDir(src + "/moby") -+ for _, f := range dirs { -+ old := fmt.Sprintf("%s/moby/%s", src, f.Name()) -+ new := fmt.Sprintf("%s/moby/%s", dst, f.Name()) -+ if e := os.Rename(old, new); e != nil { -+ if err == nil { -+ err = fmt.Errorf("mv %s %s", src, dst) -+ } -+ err = fmt.Errorf("%s %s %v", err, f.Name(), e) -+ } -+ } -+ return err -+ } -+ if err := os.MkdirAll(dst+"/moby", 0700); err != nil { -+ return fmt.Errorf("create runtime-runc failed") -+ } -+ if f, _ := os.Lstat(dst); f.Mode()&os.ModeSymlink != 0 { -+ if err := os.Rename(dst, bak(dst)); err != nil { // dst must be dir. -+ return fmt.Errorf("bak runtime-runc failed %v", err) -+ } -+ if err := os.MkdirAll(dst+"/moby", 0700); err != nil { -+ return fmt.Errorf("create runtime-runc failed") -+ } -+ if err := mov(bak(dst), dst); err != nil { -+ return err -+ } -+ } -+ -+ if f, err := os.Lstat(sym); err != nil { // sym not exist, link it. -+ return os.Symlink(dst, sym) -+ } else if f.Mode()&os.ModeSymlink != 0 { // sym is symlink, return ok. -+ return nil -+ } -+ -+ if err := os.Rename(sym, bak(sym)); err != nil { // sym must be link. -+ return fmt.Errorf("bak runtime-default failed") -+ } -+ if err := mov(bak(sym), dst); err != nil { -+ return err -+ } -+ return os.Symlink(dst, sym) -+} --- -2.19.1 - diff --git a/patch/0161-docker-Delete-stale-containerd-object-on-start-failure.patch b/patch/0161-docker-Delete-stale-containerd-object-on-start-failure.patch deleted file mode 100644 index 8d8c1cc..0000000 --- a/patch/0161-docker-Delete-stale-containerd-object-on-start-failure.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 5ba30cd1dc6000ee53b34f628cbff91d7f6d7231 Mon Sep 17 00:00:00 2001 -From: Brian Goff -Date: Wed, 12 Dec 2018 12:04:09 -0800 -Subject: [PATCH] Delete stale containerd object on start failure - -containerd has two objects with regard to containers. -There is a "container" object which is metadata and a "task" which is -manging the actual runtime state. - -When docker starts a container, it creartes both the container metadata -and the task at the same time. So when a container exits, docker deletes -both of these objects as well. - -This ensures that if, on start, when we go to create the container metadata object -in containerd, if there is an error due to a name conflict that we go -ahead and clean that up and try again. - -Signed-off-by: Brian Goff ---- - components/engine/daemon/start.go | 17 +++++++++++++++-- - 1 file changed, 15 insertions(+), 2 deletions(-) - -diff --git a/components/engine/daemon/start.go b/components/engine/daemon/start.go -index 393e00b..57a7267 100644 ---- a/components/engine/daemon/start.go -+++ b/components/engine/daemon/start.go -@@ -177,9 +177,22 @@ func (daemon *Daemon) containerStart(container *container.Container, checkpoint - return err - } - -- err = daemon.containerd.Create(context.Background(), container.ID, spec, createOptions) -+ ctx := context.TODO() -+ -+ err = daemon.containerd.Create(ctx, container.ID, spec, createOptions) - if err != nil { -- return translateContainerdStartErr(container.Path, container.SetExitCode, err) -+ if errdefs.IsConflict(err) { -+ logrus.WithError(err).WithField("container", container.ID).Error("Container not cleaned up from containerd from previous run") -+ // best effort to clean up old container object -+ daemon.containerd.DeleteTask(ctx, container.ID) -+ if err := daemon.containerd.Delete(ctx, container.ID); err != nil && !errdefs.IsNotFound(err) { -+ logrus.WithError(err).WithField("container", container.ID).Error("Error cleaning up stale containerd container object") -+ } -+ err = daemon.containerd.Create(ctx, container.ID, spec, createOptions) -+ } -+ if err != nil { -+ return translateContainerdStartErr(container.Path, container.SetExitCode, err) -+ } - } - - // TODO(mlaventure): we need to specify checkpoint options here --- -1.8.3.1 - diff --git a/patch/0162-docker-remove-redundant-word-item.patch b/patch/0162-docker-remove-redundant-word-item.patch deleted file mode 100644 index 69de191..0000000 --- a/patch/0162-docker-remove-redundant-word-item.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 92266f008637a02ebffa2aa2704a09701b07a405 Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Mon, 27 Apr 2020 09:43:21 +0800 -Subject: [PATCH] docker: remove redundant word item - -Signed-off-by: liuzekun ---- - components/cli/vendor/github.com/asaskevich/govalidator/types.go | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/components/cli/vendor/github.com/asaskevich/govalidator/types.go b/components/cli/vendor/github.com/asaskevich/govalidator/types.go -index 4f7e9274..78be68c6 100644 ---- a/components/cli/vendor/github.com/asaskevich/govalidator/types.go -+++ b/components/cli/vendor/github.com/asaskevich/govalidator/types.go -@@ -370,7 +370,6 @@ var ISO3166List = []ISO3166Entry{ - {"Spain", "Espagne (l')", "ES", "ESP", "724"}, - {"South Sudan", "Soudan du Sud (le)", "SS", "SSD", "728"}, - {"Sudan (the)", "Soudan (le)", "SD", "SDN", "729"}, -- {"Western Sahara*", "Sahara occidental (le)*", "EH", "ESH", "732"}, - {"Suriname", "Suriname (le)", "SR", "SUR", "740"}, - {"Svalbard and Jan Mayen", "Svalbard et l'Île Jan Mayen (le)", "SJ", "SJM", "744"}, - {"Swaziland", "Swaziland (le)", "SZ", "SWZ", "748"}, --- -2.19.1 - diff --git a/patch/0163-docker-delete-event-is-not-need-to-process.patch b/patch/0163-docker-delete-event-is-not-need-to-process.patch deleted file mode 100644 index fef6e36..0000000 --- a/patch/0163-docker-delete-event-is-not-need-to-process.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0fe29ca9d45ddcb36f009a8da5f858f49a8e2844 Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Wed, 8 Apr 2020 17:32:03 +0800 -Subject: [PATCH] docker: delete event is not need to access processEvent - -reason: delete event is not need to access processEvent, continue it - -Signed-off-by: liuzekun ---- - components/engine/libcontainerd/client_daemon.go | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/components/engine/libcontainerd/client_daemon.go b/components/engine/libcontainerd/client_daemon.go -index 858d6429..05c439c5 100755 ---- a/components/engine/libcontainerd/client_daemon.go -+++ b/components/engine/libcontainerd/client_daemon.go -@@ -895,6 +895,7 @@ func (c *client) processEventStream(ctx context.Context, ns string) { - "ExitStatus": t.ExitStatus, - "ExitedAt": t.ExitedAt, - }).Infof("event") -+ continue - default: - c.logger.WithFields(logrus.Fields{ - "topic": ev.Topic, --- -2.19.1 - diff --git a/patch/0164-docker-stat-process-exit-file-when-kill-process-dire.patch b/patch/0164-docker-stat-process-exit-file-when-kill-process-dire.patch deleted file mode 100644 index 4fbb7de..0000000 --- a/patch/0164-docker-stat-process-exit-file-when-kill-process-dire.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 3f285224ade14c9d64dfc81cf9b5d969343a641e Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Wed, 8 Apr 2020 19:49:38 +0800 -Subject: [PATCH] docker: stat process exit file when kill process directly - -reason: stat process exit file when kill process directly - -Signed-off-by: liuzekun ---- - components/engine/daemon/container_operations_unix.go | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/components/engine/daemon/container_operations_unix.go b/components/engine/daemon/container_operations_unix.go -index 2cc2b2e3..df2f3261 100644 ---- a/components/engine/daemon/container_operations_unix.go -+++ b/components/engine/daemon/container_operations_unix.go -@@ -346,6 +346,16 @@ func killProcessDirectly(cntr *container.Container) error { - // Ensure that we don't kill ourselves - if pid := cntr.GetPID(); pid != 0 { - logrus.Infof("Container %s failed to exit within 10 seconds of kill - trying direct SIGKILL", stringid.TruncateID(cntr.ID)) -+ pattern := fmt.Sprintf("/var/run/docker/containerd/exit/moby/%s.%d.*", cntr.ID, pid) -+ efiles, err := filepath.Glob(pattern) -+ if err != nil { -+ logrus.Warnf("Match exit file with pattern %q failed: %s", pattern, err.Error()) -+ } -+ if len(efiles) != 0 { -+ logrus.Infof("Find process exit files with pattern %q: %+v, skip force kill because the process is exit already", pattern, efiles) -+ return errNoSuchProcess{pid, 9} -+ } -+ - if err := unix.Kill(pid, 9); err != nil { - if err != unix.ESRCH { - return err --- -2.19.1 - diff --git a/patch/0164-docker-use-git-commit-to-store-commit-ID.patch b/patch/0164-docker-use-git-commit-to-store-commit-ID.patch deleted file mode 100644 index b96c4ae..0000000 --- a/patch/0164-docker-use-git-commit-to-store-commit-ID.patch +++ /dev/null @@ -1,39 +0,0 @@ -From edfe32735e5eaf614107710c8a187eddf0ccac89 Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Wed, 10 Jun 2020 01:44:18 +0800 -Subject: [PATCH] docker: use git-commit to store commit ID - -Signed-off-by: xiadanni1 ---- - components/cli/scripts/build/.variables | 2 +- - components/engine/hack/make.sh | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/components/cli/scripts/build/.variables b/components/cli/scripts/build/.variables -index 86d0e3a..a23e379 100755 ---- a/components/cli/scripts/build/.variables -+++ b/components/cli/scripts/build/.variables -@@ -4,7 +4,7 @@ set -eu - PLATFORM=${PLATFORM:-} - VERSION=${VERSION:-"unknown-version"} - EULERVERSION=${EULERVERSION:-$(cat VERSION-openeuler)} --GITCOMMIT=${GITCOMMIT:-$(git rev-parse --short HEAD 2> /dev/null || true)} -+GITCOMMIT=${GITCOMMIT:-$(cat git-commit | head -c 7)} - BUILDTIME=${BUILDTIME:-$(date --utc --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/')} - - PLATFORM_LDFLAGS= -diff --git a/components/engine/hack/make.sh b/components/engine/hack/make.sh -index 686e688..f4a51e7 100755 ---- a/components/engine/hack/make.sh -+++ b/components/engine/hack/make.sh -@@ -68,6 +68,7 @@ DEFAULT_BUNDLES=( - VERSION_EULER=$(< ./VERSION-openeuler) - VERSION=${VERSION:-dev} - ! BUILDTIME=$(date -u -d "@${SOURCE_DATE_EPOCH:-$(date +%s)}" --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/') -+DOCKER_GITCOMMIT=$(cat git-commit | head -c 7) - if [ "$DOCKER_GITCOMMIT" ]; then - GITCOMMIT="$DOCKER_GITCOMMIT" - elif command -v git &> /dev/null && [ -e .git ] && git rev-parse &> /dev/null; then --- -1.8.3.1 - diff --git a/patch/0165-docker-sync-cli-vendor.patch b/patch/0165-docker-sync-cli-vendor.patch deleted file mode 100644 index cfdcee2..0000000 --- a/patch/0165-docker-sync-cli-vendor.patch +++ /dev/null @@ -1,38 +0,0 @@ -From c4ead7f7e914244e43eab849cf68c34c3460b41c Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 14 May 2020 22:57:37 +0800 -Subject: [PATCH] docker: sync cli vendor - -Change-Id: I9dbfd3e2c918d47806abdcdc27bf709c0e297780 -Signed-off-by: jingrui ---- - .../docker/docker/builder/remotecontext/git/gitutils.go | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/components/cli/vendor/github.com/docker/docker/builder/remotecontext/git/gitutils.go b/components/cli/vendor/github.com/docker/docker/builder/remotecontext/git/gitutils.go -index 77a45beff3..a9079153e0 100644 ---- a/components/cli/vendor/github.com/docker/docker/builder/remotecontext/git/gitutils.go -+++ b/components/cli/vendor/github.com/docker/docker/builder/remotecontext/git/gitutils.go -@@ -102,6 +102,10 @@ func parseRemoteURL(remoteURL string) (gitRepo, error) { - u.Fragment = "" - repo.remote = u.String() - } -+ -+ if strings.HasPrefix(repo.ref, "-") { -+ return gitRepo{}, errors.Errorf("invalid refspec: %s", repo.ref) -+ } - return repo, nil - } - -@@ -124,7 +128,7 @@ func fetchArgs(remoteURL string, ref string) []string { - args = append(args, "--depth", "1") - } - -- return append(args, "origin", ref) -+ return append(args, "origin", "--", ref) - } - - // Check if a given git URL supports a shallow git clone, --- -2.17.1 - diff --git a/patch/0167-docker-fix-CVE-2020-13401.patch b/patch/0167-docker-fix-CVE-2020-13401.patch deleted file mode 100644 index b3bd2b3..0000000 --- a/patch/0167-docker-fix-CVE-2020-13401.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 727ce265564d1dc3031221a84f95abad20a20f11 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Thu, 11 Jun 2020 21:55:49 +0800 -Subject: [PATCH] docker: fix CVE-2020-13401 - -Change-Id: I267bde21d88927a0beb7599651b856a2dd1371d3 -Signed-off-by: jingrui ---- - .../libnetwork/drivers/bridge/bridge.go | 6 ++++++ - .../libnetwork/drivers/bridge/setup_device.go | 19 +++++++++++++++++++ - 2 files changed, 25 insertions(+) - -diff --git a/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/bridge.go b/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/bridge.go -index 535da3c1ad..3288ff8652 100644 ---- a/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/bridge.go -+++ b/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/bridge.go -@@ -679,6 +679,12 @@ func (d *driver) createNetwork(config *networkConfiguration) (err error) { - bridgeAlreadyExists := bridgeIface.exists() - if !bridgeAlreadyExists { - bridgeSetup.queueStep(setupDevice) -+ bridgeSetup.queueStep(setupDefaultSysctl) -+ } -+ -+ // For the default bridge, set expected sysctls -+ if config.DefaultBridge { -+ bridgeSetup.queueStep(setupDefaultSysctl) - } - - // Even if a bridge exists try to setup IPv4. -diff --git a/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/setup_device.go b/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/setup_device.go -index a9dfd06771..9822236dfd 100644 ---- a/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/setup_device.go -+++ b/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/setup_device.go -@@ -2,6 +2,9 @@ package bridge - - import ( - "fmt" -+ "io/ioutil" -+ "os" -+ "path/filepath" - - "github.com/docker/docker/pkg/parsers/kernel" - "github.com/docker/libnetwork/netutils" -@@ -50,6 +53,22 @@ func setupDevice(config *networkConfiguration, i *bridgeInterface) error { - return err - } - -+func setupDefaultSysctl(config *networkConfiguration, i *bridgeInterface) error { -+ // Disable IPv6 router advertisements originating on the bridge -+ sysPath := filepath.Join("/proc/sys/net/ipv6/conf/", config.BridgeName, "accept_ra") -+ if _, err := os.Stat(sysPath); err != nil { -+ logrus. -+ WithField("bridge", config.BridgeName). -+ WithField("syspath", sysPath). -+ Info("failed to read ipv6 net.ipv6.conf..accept_ra") -+ return nil -+ } -+ if err := ioutil.WriteFile(sysPath, []byte{'0', '\n'}, 0644); err != nil { -+ return fmt.Errorf("libnetwork: Unable to disable IPv6 router advertisement: %v", err) -+ } -+ return nil -+} -+ - // SetupDeviceUp ups the given bridge interface. - func setupDeviceUp(config *networkConfiguration, i *bridgeInterface) error { - err := i.nlh.LinkSetUp(i.Link) --- -2.17.1 - diff --git a/patch/0167-dockerd-add-more-messages-for-ops-when-device-not-fo.patch b/patch/0167-dockerd-add-more-messages-for-ops-when-device-not-fo.patch deleted file mode 100644 index 4863e76..0000000 --- a/patch/0167-dockerd-add-more-messages-for-ops-when-device-not-fo.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 19ce3a9a435ddb67a4e7a081cd23bb5cc19abc92 Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Thu, 30 Jul 2020 05:09:42 -0400 -Subject: [PATCH] dockerd: add more messages for ops when device not found in - the host - -Signed-off-by: liuzekun ---- - components/engine/daemon/daemon_unix.go | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index 5a59b324..af50fa37 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -262,7 +262,7 @@ func getBlkioThrottleDevices(devs []*blkiodev.ThrottleDevice) ([]specs.LinuxThro - - for _, d := range devs { - if err := unix.Stat(d.Path, &stat); err != nil { -- return nil, err -+ return nil, errors.Wrapf(err, "Failed to stat device %q", d.Path) - } - d := specs.LinuxThrottleDevice{Rate: d.Rate} - d.Major = int64(stat.Rdev / 256) --- -2.19.1 - diff --git a/patch/0168-docker-do-not-add-w-to-LDFLAGS.patch b/patch/0168-docker-do-not-add-w-to-LDFLAGS.patch deleted file mode 100644 index 5486839..0000000 --- a/patch/0168-docker-do-not-add-w-to-LDFLAGS.patch +++ /dev/null @@ -1,79 +0,0 @@ -From b23e7a179e68f194516b542bea375c44122e1037 Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Tue, 11 Aug 2020 08:00:12 +0800 -Subject: [PATCH] docker: do not add "-w" to LDFLAG - -reason: for gdb debug, do not add "-w" to LDFLAGS - -Signed-off-by: xiadanni1 ---- - components/cli/scripts/build/.variables | 1 - - components/cli/scripts/build/dynbinary | 5 ++++- - components/engine/hack/make.sh | 5 ----- - components/engine/hack/make/.binary | 5 ++++- - 4 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/components/cli/scripts/build/.variables b/components/cli/scripts/build/.variables -index a23e379..7b78e62 100755 ---- a/components/cli/scripts/build/.variables -+++ b/components/cli/scripts/build/.variables -@@ -13,7 +13,6 @@ if test -n "${PLATFORM}"; then - fi - - export LDFLAGS="\ -- -w \ - ${PLATFORM_LDFLAGS} \ - -X \"github.com/docker/cli/cli.GitCommit=${GITCOMMIT}\" \ - -X \"github.com/docker/cli/cli.BuildTime=${BUILDTIME}\" \ -diff --git a/components/cli/scripts/build/dynbinary b/components/cli/scripts/build/dynbinary -index 2442166..40941bb 100755 ---- a/components/cli/scripts/build/dynbinary -+++ b/components/cli/scripts/build/dynbinary -@@ -13,7 +13,10 @@ export CGO_ENABLED=1 - BEP_DIR=/tmp/docker-build-bep - BEP_FLAGS="-tmpdir=$BEP_DIR" - mkdir -p $BEP_DIR -+GC_FLAGS="-gcflags=-trimpath=$GOPATH" -+ASM_FLAGS="-asmflags=-trimpath=$GOPATH" - --go build -o "${TARGET}" -tags pkcs11 --ldflags " -buildid=IdByIsula -extldflags=-zrelro -extldflags=-znow $BEP_FLAGS ${LDFLAGS}" -buildmode=pie "${SOURCE}" -+set -x -+go build $GC_FLAGS $ASM_FLAGS -o "${TARGET}" -tags pkcs11 --ldflags " -buildid=IdByIsula -extldflags=-zrelro -extldflags=-znow $BEP_FLAGS ${LDFLAGS}" -buildmode=pie "${SOURCE}" - - ln -sf "$(basename "${TARGET}")" build/docker -diff --git a/components/engine/hack/make.sh b/components/engine/hack/make.sh -index f4a51e7..d24a7b7 100755 ---- a/components/engine/hack/make.sh -+++ b/components/engine/hack/make.sh -@@ -137,12 +137,7 @@ if \ - fi - - # Use these flags when compiling the tests and final binary -- - IAMSTATIC='true' --if [ -z "$DOCKER_DEBUG" ]; then -- LDFLAGS='-w' --fi -- - LDFLAGS_STATIC='' - EXTLDFLAGS_STATIC='-static' - # ORIG_BUILDFLAGS is necessary for the cross target which cannot always build -diff --git a/components/engine/hack/make/.binary b/components/engine/hack/make/.binary -index f76b6f7..35bb836 100755 ---- a/components/engine/hack/make/.binary -+++ b/components/engine/hack/make/.binary -@@ -63,7 +63,10 @@ echo "Building: $DEST/$BINARY_FULLNAME" - BEP_DIR=/tmp/dockerd-build-bep - BEP_FLAGS="-tmpdir=$BEP_DIR" - mkdir -p $BEP_DIR --go build \ -+GC_FLAGS="-gcflags=-trimpath=$GOPATH" -+ASM_FLAGS="-asmflags=-trimpath=$GOPATH" -+set -x -+go build $GC_FLAGS $ASM_FLAGS \ - -o "$DEST/$BINARY_FULLNAME" \ - "${BUILDFLAGS[@]}" \ - -ldflags " --- -1.8.3.1 - diff --git a/patch/0169-docker-add-files-in-proc-for-mask.patch b/patch/0169-docker-add-files-in-proc-for-mask.patch deleted file mode 100644 index 18d6522..0000000 --- a/patch/0169-docker-add-files-in-proc-for-mask.patch +++ /dev/null @@ -1,42 +0,0 @@ -From c9db33aaad779afff04db8beb5b6d7e7e512a66d Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Mon, 24 Aug 2020 09:42:21 -0400 -Subject: [PATCH] docker: add files in proc for mask - -Signed-off-by: liuzekun ---- - components/engine/oci/defaults.go | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/components/engine/oci/defaults.go b/components/engine/oci/defaults.go -index cd4985f5..ec748a6d 100644 ---- a/components/engine/oci/defaults.go -+++ b/components/engine/oci/defaults.go -@@ -65,7 +65,7 @@ func DefaultLinuxSpec() specs.Spec { - Effective: defaultCapabilities(), - }, - }, -- Root: &specs.Root{}, -+ Root: &specs.Root{}, - Hooks: &specs.Hooks{}, - } - s.Mounts = []specs.Mount{ -@@ -128,9 +128,15 @@ func DefaultLinuxSpec() specs.Spec { - "/proc/keys", - "/proc/latency_stats", - "/proc/livepatch", -+ "/proc/lru_info", -+ "/proc/lru_info_file", - "/proc/memstat", - "/proc/net_namespace", - "/proc/oom_extend", -+ "/proc/pagealloc_statistics", -+ "/proc/pagealloc_bt", -+ "/proc/slaballoc_bt", -+ "/proc/slaballoc_module", - "/proc/sched_debug", - "/proc/scsi", - "/proc/sig_catch", --- -2.19.1 - diff --git a/patch/0170-docker-fix-docker-load-files-leak.patch b/patch/0170-docker-fix-docker-load-files-leak.patch deleted file mode 100644 index 75bfa1b..0000000 --- a/patch/0170-docker-fix-docker-load-files-leak.patch +++ /dev/null @@ -1,27 +0,0 @@ -From e7dd426dc3d962eae0e934dcb8fe4d805f8ea4ca Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Wed, 16 Sep 2020 22:40:49 -0400 -Subject: [PATCH] fix docker load files leak - -Signed-off-by: liuzekun ---- - components/engine/daemon/graphdriver/devmapper/deviceset.go | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/components/engine/daemon/graphdriver/devmapper/deviceset.go b/components/engine/daemon/graphdriver/devmapper/deviceset.go -index f5c0b04..ff90c44 100644 ---- a/components/engine/daemon/graphdriver/devmapper/deviceset.go -+++ b/components/engine/daemon/graphdriver/devmapper/deviceset.go -@@ -2285,6 +2285,9 @@ func (devices *DeviceSet) unmountAndDeactivateAll(dir string) { - // and the device will be released when that container dies. - if err := unix.Unmount(fullname, unix.MNT_DETACH); err != nil && err != unix.EINVAL { - logger.Warnf("Shutdown unmounting %s, error: %s", fullname, err) -+ } else if err == nil { -+ logger.Debugf("Remove %s", fullname) -+ os.RemoveAll(fullname) - } - - if devInfo, err := devices.lookupDevice(name); err != nil { --- -2.19.1 - diff --git a/patch/0171-docker-do-not-sync-if-BYPAAS_SYNC-is-false.patch b/patch/0171-docker-do-not-sync-if-BYPAAS_SYNC-is-false.patch deleted file mode 100644 index 63334a2..0000000 --- a/patch/0171-docker-do-not-sync-if-BYPAAS_SYNC-is-false.patch +++ /dev/null @@ -1,28 +0,0 @@ -From bbc6fce3870ff7f43c87efe13247bb185817aa67 Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Wed, 14 Oct 2020 04:36:56 -0400 -Subject: [PATCH] do not sync if BYPAAS_SYNC is false - -Signed-off-by: liuzekun ---- - components/engine/pkg/devicemapper/devmapper.go | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/components/engine/pkg/devicemapper/devmapper.go b/components/engine/pkg/devicemapper/devmapper.go -index 06ddc3e9..a5c30cb3 100644 ---- a/components/engine/pkg/devicemapper/devmapper.go -+++ b/components/engine/pkg/devicemapper/devmapper.go -@@ -477,7 +477,9 @@ func BlockDeviceDiscard(path string) error { - - // Without this sometimes the remove of the device that happens after - // discard fails with EBUSY. -- unix.Sync() -+ if os.Getenv("DOCKER_BYPASS_SYNC_SYSCALL") != "false" { -+ unix.Sync() -+ } - - return nil - } --- -2.19.1 - diff --git a/patch/0172-docker-fix-panic-on-single-character-volumes.patch b/patch/0172-docker-fix-panic-on-single-character-volumes.patch deleted file mode 100644 index f0bdb97..0000000 --- a/patch/0172-docker-fix-panic-on-single-character-volumes.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0a2c746c0d560d18502f84078d233166934e9eb9 Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Wed, 11 Nov 2020 23:47:30 -0500 -Subject: [PATCH] fix panic on single-character volumes - -Signed-off-by: liuzekun ---- - components/cli/cli/compose/loader/volume.go | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/components/cli/cli/compose/loader/volume.go b/components/cli/cli/compose/loader/volume.go -index 9c2792e0..f043f4aa 100644 ---- a/components/cli/cli/compose/loader/volume.go -+++ b/components/cli/cli/compose/loader/volume.go -@@ -111,6 +111,9 @@ func isFilePath(source string) bool { - case '.', '/', '~': - return true - } -+ if len([]rune(source)) == 1 { -+ return false -+ } - - // windows named pipes - if strings.HasPrefix(source, `\\`) { --- -2.19.1 - diff --git a/patch/0173-docker-fix-stats-memory-usage-display-error.patch b/patch/0173-docker-fix-stats-memory-usage-display-error.patch deleted file mode 100644 index 08d6827..0000000 --- a/patch/0173-docker-fix-stats-memory-usage-display-error.patch +++ /dev/null @@ -1,38 +0,0 @@ -From d26341e4c447ddbb6bd289845b7b47f0e4348c62 Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Wed, 11 Nov 2020 17:35:06 +0800 -Subject: [PATCH] docker:fix stats memory usage display error - -fix stats memory usage display error -use total_inactive_file not cache to calculate memory usage -The new stat definition corresponds to containerd/CRI and cadvisor. - -https://github.com/containerd/cri/blob/c1115d4e57f55a5f45fb3efd29d3181ce26d5c6a/pkg/server/container_stats_list_unix.go#L106-L129 -https://github.com/google/cadvisor/commit/307d1b1cb320fef66fab02db749f07a459245451 - -Signed-off-by: xiadanni1 -Signed-off-by: Akihiro Suda ---- - components/cli/cli/command/container/stats_helpers.go | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/components/cli/cli/command/container/stats_helpers.go b/components/cli/cli/command/container/stats_helpers.go -index 2300ce5..c254212 100644 ---- a/components/cli/cli/command/container/stats_helpers.go -+++ b/components/cli/cli/command/container/stats_helpers.go -@@ -226,7 +226,11 @@ func calculateNetwork(network map[string]types.NetworkStats) (float64, float64) - // calculateMemUsageUnixNoCache calculate memory usage of the container. - // Page cache is intentionally excluded to avoid misinterpretation of the output. - func calculateMemUsageUnixNoCache(mem types.MemoryStats) float64 { -- return float64(mem.Usage - mem.Stats["cache"]) -+ if v, isCgroup1 := mem.Stats["total_inactive_file"]; isCgroup1 && v < mem.Usage { -+ return float64(mem.Usage - v) -+ } -+ -+ return float64(mem.Usage) - } - - func calculateMemPercentUnixNoCache(limit float64, usedNoCache float64) float64 { --- -1.8.3.1 - diff --git a/patch/0175-docker-clean-docker-load-leak-files.patch b/patch/0175-docker-clean-docker-load-leak-files.patch deleted file mode 100644 index f0a32c3..0000000 --- a/patch/0175-docker-clean-docker-load-leak-files.patch +++ /dev/null @@ -1,85 +0,0 @@ -From a74f1c3e4ab7c6f4a043904a8e68edf04864d98a Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 2 Dec 2020 17:20:50 +0800 -Subject: [PATCH] docker: clean docker load leak files - -Change-Id: I09b66e204f655a9fef660bb85619f5711fb5700b -Signed-off-by: jingrui ---- - components/engine/daemon/daemon.go | 39 +++++++++++++++++++ - .../daemon/graphdriver/devmapper/deviceset.go | 3 +- - 2 files changed, 41 insertions(+), 1 deletion(-) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 3ff5691257..1acd355a15 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -613,11 +613,50 @@ func (daemon *Daemon) restore() error { - - group.Wait() - -+ daemon.cleanExit() - logrus.Info("Loading containers: done.") - - return nil - } - -+func (daemon *Daemon) cleanExit() { -+ mnt := filepath.Join(daemon.root, "devicemapper/mnt") -+ if dir, err := ioutil.ReadDir(mnt); err == nil { -+ for _, f := range dir { -+ fname := filepath.Join(mnt, f.Name()) -+ data, err := ioutil.ReadFile(fname) -+ if err != nil { -+ continue -+ } -+ if string(data) == "exit" { -+ logrus.Infof("cleanExit remove mnt %s", fname) -+ os.Remove(fname) -+ } -+ } -+ } -+ -+ tmp := filepath.Join(daemon.root, "image/devicemapper/layerdb/tmp") -+ if dir, err := ioutil.ReadDir(tmp); err == nil { -+ for _, f := range dir { -+ if strings.Contains(f.Name(), "write-set-") { -+ fname := filepath.Join(tmp, f.Name()) -+ logrus.Infof("cleanExit remove layerdb %s", fname) -+ os.RemoveAll(fname) -+ } -+ } -+ } -+ -+ if dir, err := ioutil.ReadDir(os.Getenv("TMPDIR")); err == nil { -+ for _, f := range dir { -+ if strings.Contains(f.Name(), "docker-import-") { -+ fname := filepath.Join(os.Getenv("TMPDIR"), f.Name()) -+ logrus.Infof("cleanExit remove tmpdir %s", fname) -+ os.RemoveAll(fname) -+ } -+ } -+ } -+} -+ - // RestartSwarmContainers restarts any autostart container which has a - // swarm endpoint. - func (daemon *Daemon) RestartSwarmContainers() { -diff --git a/components/engine/daemon/graphdriver/devmapper/deviceset.go b/components/engine/daemon/graphdriver/devmapper/deviceset.go -index ff90c44ce3..750f2b13f8 100644 ---- a/components/engine/daemon/graphdriver/devmapper/deviceset.go -+++ b/components/engine/daemon/graphdriver/devmapper/deviceset.go -@@ -2286,8 +2286,9 @@ func (devices *DeviceSet) unmountAndDeactivateAll(dir string) { - if err := unix.Unmount(fullname, unix.MNT_DETACH); err != nil && err != unix.EINVAL { - logger.Warnf("Shutdown unmounting %s, error: %s", fullname, err) - } else if err == nil { -- logger.Debugf("Remove %s", fullname) -+ logger.Infof("cleanExit prepare %s", fullname) - os.RemoveAll(fullname) -+ ioutil.WriteFile(fullname, []byte("exit"), 0600) - } - - if devInfo, err := devices.lookupDevice(name); err != nil { --- -2.17.1 - diff --git a/patch/0175-docker-components-engine-vendor-add-riscv64-config.patch b/patch/0175-docker-components-engine-vendor-add-riscv64-config.patch deleted file mode 100644 index 3a6db61..0000000 --- a/patch/0175-docker-components-engine-vendor-add-riscv64-config.patch +++ /dev/null @@ -1,77 +0,0 @@ -From c97b550df673a7ceb1f801b7099476feba622130 Mon Sep 17 00:00:00 2001 -From: yangyanchao -Date: Sat, 19 Dec 2020 09:19:31 +0000 -Subject: [PATCH 1/3] docker:components:engine:vendor:add riscv64 config in - existing files - -Signed-off-by: yangyanchao ---- - .../drivers/bridge/netlink_deprecated_linux_armppc64.go | 2 +- - .../drivers/bridge/netlink_deprecated_linux_notarm.go | 2 +- - .../golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go | 2 +- - .../vendor/golang.org/x/net/internal/socket/iovec_64bit.go | 2 +- - .../golang.org/x/net/internal/socket/msghdr_linux_64bit.go | 2 +- - 5 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_armppc64.go b/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_armppc64.go -index 739d9c6..a937f50 100644 ---- a/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_armppc64.go -+++ b/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_armppc64.go -@@ -1,4 +1,4 @@ --// +build arm ppc64 ppc64le -+// +build arm ppc64 ppc64le riscv64 - - package bridge - -diff --git a/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go b/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go -index df52695..68d368c 100644 ---- a/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go -+++ b/components/engine/vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go -@@ -1,4 +1,4 @@ --// +build !arm,!ppc64,!ppc64le -+// +build !arm,!ppc64,!ppc64le,!riscv64 - - package bridge - -diff --git a/components/engine/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go b/components/engine/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go -index 63f0534..852a71b 100644 ---- a/components/engine/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go -+++ b/components/engine/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go -@@ -2,7 +2,7 @@ - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. - --// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x -+// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x riscv64 - // +build linux - - package socket -diff --git a/components/engine/vendor/golang.org/x/net/internal/socket/iovec_64bit.go b/components/engine/vendor/golang.org/x/net/internal/socket/iovec_64bit.go -index afb34ad..a2b17e2 100644 ---- a/components/engine/vendor/golang.org/x/net/internal/socket/iovec_64bit.go -+++ b/components/engine/vendor/golang.org/x/net/internal/socket/iovec_64bit.go -@@ -2,7 +2,7 @@ - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. - --// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x -+// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x riscv64 - // +build darwin dragonfly freebsd linux netbsd openbsd - - package socket -diff --git a/components/engine/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go b/components/engine/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go -index 610fc4f..375d402 100644 ---- a/components/engine/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go -+++ b/components/engine/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go -@@ -2,7 +2,7 @@ - // Use of this source code is governed by a BSD-style - // license that can be found in the LICENSE file. - --// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x -+// +build arm64 amd64 ppc64 ppc64le mips64 mips64le s390x riscv64 - // +build linux - - package socket --- -2.23.0 - diff --git a/patch/0175-docker-mask-proc-pin_memory.patch b/patch/0175-docker-mask-proc-pin_memory.patch deleted file mode 100644 index 4b0502d..0000000 --- a/patch/0175-docker-mask-proc-pin_memory.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 017c3377f0bd5230c0fa1699bd193baa527f0b8f Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Fri, 20 Nov 2020 18:34:45 +0800 -Subject: [PATCH] docker:mask /proc/pin_memory - -Signed-off-by: xiadanni1 ---- - components/engine/oci/defaults.go | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/components/engine/oci/defaults.go b/components/engine/oci/defaults.go -index ec748a6..e763cb7 100644 ---- a/components/engine/oci/defaults.go -+++ b/components/engine/oci/defaults.go -@@ -135,6 +135,7 @@ func DefaultLinuxSpec() specs.Spec { - "/proc/oom_extend", - "/proc/pagealloc_statistics", - "/proc/pagealloc_bt", -+ "/proc/pin_memory", - "/proc/slaballoc_bt", - "/proc/slaballoc_module", - "/proc/sched_debug", --- -1.8.3.1 - diff --git a/patch/0176-docker-components-engine-vendor-add-new-config-file-for-riscv.patch b/patch/0176-docker-components-engine-vendor-add-new-config-file-for-riscv.patch deleted file mode 100644 index 5649ae5..0000000 --- a/patch/0176-docker-components-engine-vendor-add-new-config-file-for-riscv.patch +++ /dev/null @@ -1,8079 +0,0 @@ -From 77b9226adf50303499971c5cd42298026be79031 Mon Sep 17 00:00:00 2001 -From: yangyanchao -Date: Sat, 19 Dec 2020 09:22:30 +0000 -Subject: [PATCH 2/3] docker:components:engine:vendor:add new config files for - riscv64 - -Signed-off-by: yangyanchao ---- - .../vishvananda/netns/netns_linux_riscv64.go | 7 + - .../vendor/go.etcd.io/bbolt/bolt_riscv64.go | 12 + - .../net/internal/socket/sys_linux_riscv64.go | 10 + - .../net/internal/socket/zsys_linux_riscv64.go | 66 + - .../x/net/ipv4/zsys_linux_riscv64.go | 152 + - .../x/net/ipv6/zsys_linux_riscv64.go | 173 + - .../golang.org/x/sys/unix/asm_linux_riscv64.s | 47 + - .../x/sys/unix/syscall_linux_riscv64.go | 213 ++ - .../x/sys/unix/zerrors_linux_riscv64.go | 2769 +++++++++++++++++ - .../x/sys/unix/zsyscall_linux_riscv64.go | 2188 +++++++++++++ - .../x/sys/unix/zsysnum_linux_riscv64.go | 287 ++ - .../x/sys/unix/ztypes_linux_riscv64.go | 2046 ++++++++++++ - 12 files changed, 7970 insertions(+) - create mode 100644 components/engine/vendor/github.com/vishvananda/netns/netns_linux_riscv64.go - create mode 100644 components/engine/vendor/go.etcd.io/bbolt/bolt_riscv64.go - create mode 100644 components/engine/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go - create mode 100644 components/engine/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go - create mode 100644 components/engine/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go - create mode 100644 components/engine/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go - create mode 100644 components/engine/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s - create mode 100644 components/engine/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go - create mode 100644 components/engine/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go - create mode 100644 components/engine/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go - create mode 100644 components/engine/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go - create mode 100644 components/engine/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go - -diff --git a/components/engine/vendor/github.com/vishvananda/netns/netns_linux_riscv64.go b/components/engine/vendor/github.com/vishvananda/netns/netns_linux_riscv64.go -new file mode 100644 -index 0000000..1576985 ---- /dev/null -+++ b/components/engine/vendor/github.com/vishvananda/netns/netns_linux_riscv64.go -@@ -0,0 +1,7 @@ -+// +build linux,riscv64 -+ -+package netns -+ -+const ( -+ SYS_SETNS = 268 -+) -diff --git a/components/engine/vendor/go.etcd.io/bbolt/bolt_riscv64.go b/components/engine/vendor/go.etcd.io/bbolt/bolt_riscv64.go -new file mode 100644 -index 0000000..b5a6b1d ---- /dev/null -+++ b/components/engine/vendor/go.etcd.io/bbolt/bolt_riscv64.go -@@ -0,0 +1,12 @@ -+// +build riscv64 -+ -+package bbolt -+ -+// maxMapSize represents the largest mmap size supported by Bolt. -+const maxMapSize = 0xFFFFFFFFFFFF // 256TB -+ -+// maxAllocSize is the size used when creating array pointers. -+const maxAllocSize = 0x7FFFFFFF -+ -+// Are unaligned load/stores broken on this arch? -+var brokenUnaligned = false -diff --git a/components/engine/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go b/components/engine/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go -new file mode 100644 -index 0000000..b670894 ---- /dev/null -+++ b/components/engine/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go -@@ -0,0 +1,10 @@ -+// Copyright 2017 The Go Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style -+// license that can be found in the LICENSE file. -+ -+package socket -+ -+const ( -+ sysRECVMMSG = 0xf3 -+ sysSENDMMSG = 0x10d -+) -diff --git a/components/engine/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go b/components/engine/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go -new file mode 100644 -index 0000000..1502f6c ---- /dev/null -+++ b/components/engine/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go -@@ -0,0 +1,66 @@ -+// Created by cgo -godefs - DO NOT EDIT -+// cgo -godefs defs_linux.go -+ -+package socket -+ -+const ( -+ sysAF_UNSPEC = 0x0 -+ sysAF_INET = 0x2 -+ sysAF_INET6 = 0xa -+ -+ sysSOCK_RAW = 0x3 -+) -+ -+type iovec struct { -+ Base *byte -+ Len uint64 -+} -+ -+type msghdr struct { -+ Name *byte -+ Namelen uint32 -+ Pad_cgo_0 [4]byte -+ Iov *iovec -+ Iovlen uint64 -+ Control *byte -+ Controllen uint64 -+ Flags int32 -+ Pad_cgo_1 [4]byte -+} -+ -+type mmsghdr struct { -+ Hdr msghdr -+ Len uint32 -+ Pad_cgo_0 [4]byte -+} -+ -+type cmsghdr struct { -+ Len uint64 -+ Level int32 -+ Type int32 -+} -+ -+type sockaddrInet struct { -+ Family uint16 -+ Port uint16 -+ Addr [4]byte /* in_addr */ -+ X__pad [8]uint8 -+} -+ -+type sockaddrInet6 struct { -+ Family uint16 -+ Port uint16 -+ Flowinfo uint32 -+ Addr [16]byte /* in6_addr */ -+ Scope_id uint32 -+} -+ -+const ( -+ sizeofIovec = 0x10 -+ sizeofMsghdr = 0x38 -+ sizeofMmsghdr = 0x40 -+ sizeofCmsghdr = 0x10 -+ -+ sizeofSockaddrInet = 0x10 -+ sizeofSockaddrInet6 = 0x1c -+) -diff --git a/components/engine/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go b/components/engine/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go -new file mode 100644 -index 0000000..6905697 ---- /dev/null -+++ b/components/engine/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go -@@ -0,0 +1,152 @@ -+// Code generated by cmd/cgo -godefs; DO NOT EDIT. -+// cgo -godefs defs_linux.go -+ -+// +build riscv64 -+ -+package ipv4 -+ -+const ( -+ sysIP_TOS = 0x1 -+ sysIP_TTL = 0x2 -+ sysIP_HDRINCL = 0x3 -+ sysIP_OPTIONS = 0x4 -+ sysIP_ROUTER_ALERT = 0x5 -+ sysIP_RECVOPTS = 0x6 -+ sysIP_RETOPTS = 0x7 -+ sysIP_PKTINFO = 0x8 -+ sysIP_PKTOPTIONS = 0x9 -+ sysIP_MTU_DISCOVER = 0xa -+ sysIP_RECVERR = 0xb -+ sysIP_RECVTTL = 0xc -+ sysIP_RECVTOS = 0xd -+ sysIP_MTU = 0xe -+ sysIP_FREEBIND = 0xf -+ sysIP_TRANSPARENT = 0x13 -+ sysIP_RECVRETOPTS = 0x7 -+ sysIP_ORIGDSTADDR = 0x14 -+ sysIP_RECVORIGDSTADDR = 0x14 -+ sysIP_MINTTL = 0x15 -+ sysIP_NODEFRAG = 0x16 -+ sysIP_UNICAST_IF = 0x32 -+ -+ sysIP_MULTICAST_IF = 0x20 -+ sysIP_MULTICAST_TTL = 0x21 -+ sysIP_MULTICAST_LOOP = 0x22 -+ sysIP_ADD_MEMBERSHIP = 0x23 -+ sysIP_DROP_MEMBERSHIP = 0x24 -+ sysIP_UNBLOCK_SOURCE = 0x25 -+ sysIP_BLOCK_SOURCE = 0x26 -+ sysIP_ADD_SOURCE_MEMBERSHIP = 0x27 -+ sysIP_DROP_SOURCE_MEMBERSHIP = 0x28 -+ sysIP_MSFILTER = 0x29 -+ sysMCAST_JOIN_GROUP = 0x2a -+ sysMCAST_LEAVE_GROUP = 0x2d -+ sysMCAST_JOIN_SOURCE_GROUP = 0x2e -+ sysMCAST_LEAVE_SOURCE_GROUP = 0x2f -+ sysMCAST_BLOCK_SOURCE = 0x2b -+ sysMCAST_UNBLOCK_SOURCE = 0x2c -+ sysMCAST_MSFILTER = 0x30 -+ sysIP_MULTICAST_ALL = 0x31 -+ -+ sysICMP_FILTER = 0x1 -+ -+ sysSO_EE_ORIGIN_NONE = 0x0 -+ sysSO_EE_ORIGIN_LOCAL = 0x1 -+ sysSO_EE_ORIGIN_ICMP = 0x2 -+ sysSO_EE_ORIGIN_ICMP6 = 0x3 -+ sysSO_EE_ORIGIN_TXSTATUS = 0x4 -+ sysSO_EE_ORIGIN_TIMESTAMPING = 0x4 -+ -+ sysSOL_SOCKET = 0x1 -+ sysSO_ATTACH_FILTER = 0x1a -+ -+ sizeofKernelSockaddrStorage = 0x80 -+ sizeofSockaddrInet = 0x10 -+ sizeofInetPktinfo = 0xc -+ sizeofSockExtendedErr = 0x10 -+ -+ sizeofIPMreq = 0x8 -+ sizeofIPMreqn = 0xc -+ sizeofIPMreqSource = 0xc -+ sizeofGroupReq = 0x88 -+ sizeofGroupSourceReq = 0x108 -+ -+ sizeofICMPFilter = 0x4 -+ -+ sizeofSockFprog = 0x10 -+) -+ -+type kernelSockaddrStorage struct { -+ Family uint16 -+ X__data [126]int8 -+} -+ -+type sockaddrInet struct { -+ Family uint16 -+ Port uint16 -+ Addr [4]byte /* in_addr */ -+ X__pad [8]uint8 -+} -+ -+type inetPktinfo struct { -+ Ifindex int32 -+ Spec_dst [4]byte /* in_addr */ -+ Addr [4]byte /* in_addr */ -+} -+ -+type sockExtendedErr struct { -+ Errno uint32 -+ Origin uint8 -+ Type uint8 -+ Code uint8 -+ Pad uint8 -+ Info uint32 -+ Data uint32 -+} -+ -+type ipMreq struct { -+ Multiaddr [4]byte /* in_addr */ -+ Interface [4]byte /* in_addr */ -+} -+ -+type ipMreqn struct { -+ Multiaddr [4]byte /* in_addr */ -+ Address [4]byte /* in_addr */ -+ Ifindex int32 -+} -+ -+type ipMreqSource struct { -+ Multiaddr uint32 -+ Interface uint32 -+ Sourceaddr uint32 -+} -+ -+type groupReq struct { -+ Interface uint32 -+ Pad_cgo_0 [4]byte -+ Group kernelSockaddrStorage -+} -+ -+type groupSourceReq struct { -+ Interface uint32 -+ Pad_cgo_0 [4]byte -+ Group kernelSockaddrStorage -+ Source kernelSockaddrStorage -+} -+ -+type icmpFilter struct { -+ Data uint32 -+} -+ -+type sockFProg struct { -+ Len uint16 -+ Pad_cgo_0 [6]byte -+ Filter *sockFilter -+} -+ -+type sockFilter struct { -+ Code uint16 -+ Jt uint8 -+ Jf uint8 -+ K uint32 -+} -diff --git a/components/engine/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go b/components/engine/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go -new file mode 100644 -index 0000000..78017ef ---- /dev/null -+++ b/components/engine/vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go -@@ -0,0 +1,173 @@ -+// Code generated by cmd/cgo -godefs; DO NOT EDIT. -+// cgo -godefs defs_linux.go -+ -+// +build riscv64 -+ -+package ipv6 -+ -+const ( -+ sysIPV6_ADDRFORM = 0x1 -+ sysIPV6_2292PKTINFO = 0x2 -+ sysIPV6_2292HOPOPTS = 0x3 -+ sysIPV6_2292DSTOPTS = 0x4 -+ sysIPV6_2292RTHDR = 0x5 -+ sysIPV6_2292PKTOPTIONS = 0x6 -+ sysIPV6_CHECKSUM = 0x7 -+ sysIPV6_2292HOPLIMIT = 0x8 -+ sysIPV6_NEXTHOP = 0x9 -+ sysIPV6_FLOWINFO = 0xb -+ -+ sysIPV6_UNICAST_HOPS = 0x10 -+ sysIPV6_MULTICAST_IF = 0x11 -+ sysIPV6_MULTICAST_HOPS = 0x12 -+ sysIPV6_MULTICAST_LOOP = 0x13 -+ sysIPV6_ADD_MEMBERSHIP = 0x14 -+ sysIPV6_DROP_MEMBERSHIP = 0x15 -+ sysMCAST_JOIN_GROUP = 0x2a -+ sysMCAST_LEAVE_GROUP = 0x2d -+ sysMCAST_JOIN_SOURCE_GROUP = 0x2e -+ sysMCAST_LEAVE_SOURCE_GROUP = 0x2f -+ sysMCAST_BLOCK_SOURCE = 0x2b -+ sysMCAST_UNBLOCK_SOURCE = 0x2c -+ sysMCAST_MSFILTER = 0x30 -+ sysIPV6_ROUTER_ALERT = 0x16 -+ sysIPV6_MTU_DISCOVER = 0x17 -+ sysIPV6_MTU = 0x18 -+ sysIPV6_RECVERR = 0x19 -+ sysIPV6_V6ONLY = 0x1a -+ sysIPV6_JOIN_ANYCAST = 0x1b -+ sysIPV6_LEAVE_ANYCAST = 0x1c -+ -+ sysIPV6_FLOWLABEL_MGR = 0x20 -+ sysIPV6_FLOWINFO_SEND = 0x21 -+ -+ sysIPV6_IPSEC_POLICY = 0x22 -+ sysIPV6_XFRM_POLICY = 0x23 -+ -+ sysIPV6_RECVPKTINFO = 0x31 -+ sysIPV6_PKTINFO = 0x32 -+ sysIPV6_RECVHOPLIMIT = 0x33 -+ sysIPV6_HOPLIMIT = 0x34 -+ sysIPV6_RECVHOPOPTS = 0x35 -+ sysIPV6_HOPOPTS = 0x36 -+ sysIPV6_RTHDRDSTOPTS = 0x37 -+ sysIPV6_RECVRTHDR = 0x38 -+ sysIPV6_RTHDR = 0x39 -+ sysIPV6_RECVDSTOPTS = 0x3a -+ sysIPV6_DSTOPTS = 0x3b -+ sysIPV6_RECVPATHMTU = 0x3c -+ sysIPV6_PATHMTU = 0x3d -+ sysIPV6_DONTFRAG = 0x3e -+ -+ sysIPV6_RECVTCLASS = 0x42 -+ sysIPV6_TCLASS = 0x43 -+ -+ sysIPV6_ADDR_PREFERENCES = 0x48 -+ -+ sysIPV6_PREFER_SRC_TMP = 0x1 -+ sysIPV6_PREFER_SRC_PUBLIC = 0x2 -+ sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100 -+ sysIPV6_PREFER_SRC_COA = 0x4 -+ sysIPV6_PREFER_SRC_HOME = 0x400 -+ sysIPV6_PREFER_SRC_CGA = 0x8 -+ sysIPV6_PREFER_SRC_NONCGA = 0x800 -+ -+ sysIPV6_MINHOPCOUNT = 0x49 -+ -+ sysIPV6_ORIGDSTADDR = 0x4a -+ sysIPV6_RECVORIGDSTADDR = 0x4a -+ sysIPV6_TRANSPARENT = 0x4b -+ sysIPV6_UNICAST_IF = 0x4c -+ -+ sysICMPV6_FILTER = 0x1 -+ -+ sysICMPV6_FILTER_BLOCK = 0x1 -+ sysICMPV6_FILTER_PASS = 0x2 -+ sysICMPV6_FILTER_BLOCKOTHERS = 0x3 -+ sysICMPV6_FILTER_PASSONLY = 0x4 -+ -+ sysSOL_SOCKET = 0x1 -+ sysSO_ATTACH_FILTER = 0x1a -+ sizeofKernelSockaddrStorage = 0x80 -+ sizeofSockaddrInet6 = 0x1c -+ sizeofInet6Pktinfo = 0x14 -+ sizeofIPv6Mtuinfo = 0x20 -+ sizeofIPv6FlowlabelReq = 0x20 -+ -+ sizeofIPv6Mreq = 0x14 -+ sizeofGroupReq = 0x88 -+ sizeofGroupSourceReq = 0x108 -+ -+ sizeofICMPv6Filter = 0x20 -+ -+ sizeofSockFprog = 0x10 -+) -+ -+type kernelSockaddrStorage struct { -+ Family uint16 -+ X__data [126]int8 -+} -+ -+type sockaddrInet6 struct { -+ Family uint16 -+ Port uint16 -+ Flowinfo uint32 -+ Addr [16]byte /* in6_addr */ -+ Scope_id uint32 -+} -+ -+type inet6Pktinfo struct { -+ Addr [16]byte /* in6_addr */ -+ Ifindex int32 -+} -+ -+type ipv6Mtuinfo struct { -+ Addr sockaddrInet6 -+ Mtu uint32 -+} -+ -+type ipv6FlowlabelReq struct { -+ Dst [16]byte /* in6_addr */ -+ Label uint32 -+ Action uint8 -+ Share uint8 -+ Flags uint16 -+ Expires uint16 -+ Linger uint16 -+ X__flr_pad uint32 -+} -+ -+type ipv6Mreq struct { -+ Multiaddr [16]byte /* in6_addr */ -+ Ifindex int32 -+} -+ -+type groupReq struct { -+ Interface uint32 -+ Pad_cgo_0 [4]byte -+ Group kernelSockaddrStorage -+} -+ -+type groupSourceReq struct { -+ Interface uint32 -+ Pad_cgo_0 [4]byte -+ Group kernelSockaddrStorage -+ Source kernelSockaddrStorage -+} -+ -+type icmpv6Filter struct { -+ Data [8]uint32 -+} -+ -+type sockFProg struct { -+ Len uint16 -+ Pad_cgo_0 [6]byte -+ Filter *sockFilter -+} -+ -+type sockFilter struct { -+ Code uint16 -+ Jt uint8 -+ Jf uint8 -+ K uint32 -+} -diff --git a/components/engine/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s b/components/engine/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s -new file mode 100644 -index 0000000..3cfefed ---- /dev/null -+++ b/components/engine/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s -@@ -0,0 +1,47 @@ -+// Copyright 2019 The Go Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style -+// license that can be found in the LICENSE file. -+ -+// +build riscv64,!gccgo -+ -+#include "textflag.h" -+ -+// -+// System calls for linux/riscv64. -+// -+// Where available, just jump to package syscall's implementation of -+// these functions. -+ -+TEXT ·Syscall(SB),NOSPLIT,$0-56 -+ JMP syscall·Syscall(SB) -+ -+TEXT ·Syscall6(SB),NOSPLIT,$0-80 -+ JMP syscall·Syscall6(SB) -+ -+TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 -+ CALL runtime·entersyscall(SB) -+ MOV a1+8(FP), A0 -+ MOV a2+16(FP), A1 -+ MOV a3+24(FP), A2 -+ MOV trap+0(FP), A7 // syscall entry -+ ECALL -+ MOV A0, r1+32(FP) // r1 -+ MOV A1, r2+40(FP) // r2 -+ CALL runtime·exitsyscall(SB) -+ RET -+ -+TEXT ·RawSyscall(SB),NOSPLIT,$0-56 -+ JMP syscall·RawSyscall(SB) -+ -+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 -+ JMP syscall·RawSyscall6(SB) -+ -+TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 -+ MOV a1+8(FP), A0 -+ MOV a2+16(FP), A1 -+ MOV a3+24(FP), A2 -+ MOV trap+0(FP), A7 // syscall entry -+ ECALL -+ MOV A0, r1+32(FP) -+ MOV A1, r2+40(FP) -+ RET -diff --git a/components/engine/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/components/engine/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go -new file mode 100644 -index 0000000..f23ca45 ---- /dev/null -+++ b/components/engine/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go -@@ -0,0 +1,213 @@ -+// Copyright 2018 The Go Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style -+// license that can be found in the LICENSE file. -+ -+// +build riscv64,linux -+ -+package unix -+ -+import "unsafe" -+ -+func EpollCreate(size int) (fd int, err error) { -+ if size <= 0 { -+ return -1, EINVAL -+ } -+ return EpollCreate1(0) -+} -+ -+//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT -+//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 -+//sys Fchown(fd int, uid int, gid int) (err error) -+//sys Fstat(fd int, stat *Stat_t) (err error) -+//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) -+//sys Fstatfs(fd int, buf *Statfs_t) (err error) -+//sys Ftruncate(fd int, length int64) (err error) -+//sysnb Getegid() (egid int) -+//sysnb Geteuid() (euid int) -+//sysnb Getgid() (gid int) -+//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) -+//sysnb Getuid() (uid int) -+//sys Listen(s int, n int) (err error) -+//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 -+//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 -+//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK -+ -+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { -+ var ts *Timespec -+ if timeout != nil { -+ ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} -+ } -+ return Pselect(nfd, r, w, e, ts, nil) -+} -+ -+//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) -+//sys Setfsgid(gid int) (err error) -+//sys Setfsuid(uid int) (err error) -+//sysnb Setregid(rgid int, egid int) (err error) -+//sysnb Setresgid(rgid int, egid int, sgid int) (err error) -+//sysnb Setresuid(ruid int, euid int, suid int) (err error) -+//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) -+//sysnb Setreuid(ruid int, euid int) (err error) -+//sys Shutdown(fd int, how int) (err error) -+//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) -+ -+func Stat(path string, stat *Stat_t) (err error) { -+ return Fstatat(AT_FDCWD, path, stat, 0) -+} -+ -+func Lchown(path string, uid int, gid int) (err error) { -+ return Fchownat(AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW) -+} -+ -+func Lstat(path string, stat *Stat_t) (err error) { -+ return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW) -+} -+ -+//sys Statfs(path string, buf *Statfs_t) (err error) -+//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) -+//sys Truncate(path string, length int64) (err error) -+ -+func Ustat(dev int, ubuf *Ustat_t) (err error) { -+ return ENOSYS -+} -+ -+//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) -+//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) -+//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) -+//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) -+//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) -+//sysnb setgroups(n int, list *_Gid_t) (err error) -+//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) -+//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) -+//sysnb socket(domain int, typ int, proto int) (fd int, err error) -+//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) -+//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) -+//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) -+//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) -+//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) -+//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) -+//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) -+//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) -+ -+//sysnb Gettimeofday(tv *Timeval) (err error) -+ -+func setTimespec(sec, nsec int64) Timespec { -+ return Timespec{Sec: sec, Nsec: nsec} -+} -+ -+func setTimeval(sec, usec int64) Timeval { -+ return Timeval{Sec: sec, Usec: usec} -+} -+ -+func futimesat(dirfd int, path string, tv *[2]Timeval) (err error) { -+ if tv == nil { -+ return utimensat(dirfd, path, nil, 0) -+ } -+ -+ ts := []Timespec{ -+ NsecToTimespec(TimevalToNsec(tv[0])), -+ NsecToTimespec(TimevalToNsec(tv[1])), -+ } -+ return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) -+} -+ -+func Time(t *Time_t) (Time_t, error) { -+ var tv Timeval -+ err := Gettimeofday(&tv) -+ if err != nil { -+ return 0, err -+ } -+ if t != nil { -+ *t = Time_t(tv.Sec) -+ } -+ return Time_t(tv.Sec), nil -+} -+ -+func Utime(path string, buf *Utimbuf) error { -+ tv := []Timeval{ -+ {Sec: buf.Actime}, -+ {Sec: buf.Modtime}, -+ } -+ return Utimes(path, tv) -+} -+ -+func utimes(path string, tv *[2]Timeval) (err error) { -+ if tv == nil { -+ return utimensat(AT_FDCWD, path, nil, 0) -+ } -+ -+ ts := []Timespec{ -+ NsecToTimespec(TimevalToNsec(tv[0])), -+ NsecToTimespec(TimevalToNsec(tv[1])), -+ } -+ return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) -+} -+ -+func Pipe(p []int) (err error) { -+ if len(p) != 2 { -+ return EINVAL -+ } -+ var pp [2]_C_int -+ err = pipe2(&pp, 0) -+ p[0] = int(pp[0]) -+ p[1] = int(pp[1]) -+ return -+} -+ -+//sysnb pipe2(p *[2]_C_int, flags int) (err error) -+ -+func Pipe2(p []int, flags int) (err error) { -+ if len(p) != 2 { -+ return EINVAL -+ } -+ var pp [2]_C_int -+ err = pipe2(&pp, flags) -+ p[0] = int(pp[0]) -+ p[1] = int(pp[1]) -+ return -+} -+ -+func (r *PtraceRegs) PC() uint64 { return r.Pc } -+ -+func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc } -+ -+func (iov *Iovec) SetLen(length int) { -+ iov.Len = uint64(length) -+} -+ -+func (msghdr *Msghdr) SetControllen(length int) { -+ msghdr.Controllen = uint64(length) -+} -+ -+func (cmsg *Cmsghdr) SetLen(length int) { -+ cmsg.Len = uint64(length) -+} -+ -+func InotifyInit() (fd int, err error) { -+ return InotifyInit1(0) -+} -+ -+func Dup2(oldfd int, newfd int) (err error) { -+ return Dup3(oldfd, newfd, 0) -+} -+ -+func Pause() error { -+ _, err := ppoll(nil, 0, nil, nil) -+ return err -+} -+ -+func Poll(fds []PollFd, timeout int) (n int, err error) { -+ var ts *Timespec -+ if timeout >= 0 { -+ ts = new(Timespec) -+ *ts = NsecToTimespec(int64(timeout) * 1e6) -+ } -+ if len(fds) == 0 { -+ return ppoll(nil, 0, ts, nil) -+ } -+ return ppoll(&fds[0], len(fds), ts, nil) -+} -+ -+func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { -+ return Renameat2(olddirfd, oldpath, newdirfd, newpath, 0) -+} -diff --git a/components/engine/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/components/engine/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go -new file mode 100644 -index 0000000..5aea4b9 ---- /dev/null -+++ b/components/engine/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go -@@ -0,0 +1,2769 @@ -+// mkerrors.sh -Wall -Werror -static -I/tmp/include -+// Code generated by the command above; see README.md. DO NOT EDIT. -+ -+// +build riscv64,linux -+ -+// Code generated by cmd/cgo -godefs; DO NOT EDIT. -+// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go -+ -+package unix -+ -+import "syscall" -+ -+const ( -+ AAFS_MAGIC = 0x5a3c69f0 -+ ADFS_SUPER_MAGIC = 0xadf5 -+ AFFS_SUPER_MAGIC = 0xadff -+ AFS_FS_MAGIC = 0x6b414653 -+ AFS_SUPER_MAGIC = 0x5346414f -+ AF_ALG = 0x26 -+ AF_APPLETALK = 0x5 -+ AF_ASH = 0x12 -+ AF_ATMPVC = 0x8 -+ AF_ATMSVC = 0x14 -+ AF_AX25 = 0x3 -+ AF_BLUETOOTH = 0x1f -+ AF_BRIDGE = 0x7 -+ AF_CAIF = 0x25 -+ AF_CAN = 0x1d -+ AF_DECnet = 0xc -+ AF_ECONET = 0x13 -+ AF_FILE = 0x1 -+ AF_IB = 0x1b -+ AF_IEEE802154 = 0x24 -+ AF_INET = 0x2 -+ AF_INET6 = 0xa -+ AF_IPX = 0x4 -+ AF_IRDA = 0x17 -+ AF_ISDN = 0x22 -+ AF_IUCV = 0x20 -+ AF_KCM = 0x29 -+ AF_KEY = 0xf -+ AF_LLC = 0x1a -+ AF_LOCAL = 0x1 -+ AF_MAX = 0x2d -+ AF_MPLS = 0x1c -+ AF_NETBEUI = 0xd -+ AF_NETLINK = 0x10 -+ AF_NETROM = 0x6 -+ AF_NFC = 0x27 -+ AF_PACKET = 0x11 -+ AF_PHONET = 0x23 -+ AF_PPPOX = 0x18 -+ AF_QIPCRTR = 0x2a -+ AF_RDS = 0x15 -+ AF_ROSE = 0xb -+ AF_ROUTE = 0x10 -+ AF_RXRPC = 0x21 -+ AF_SECURITY = 0xe -+ AF_SMC = 0x2b -+ AF_SNA = 0x16 -+ AF_TIPC = 0x1e -+ AF_UNIX = 0x1 -+ AF_UNSPEC = 0x0 -+ AF_VSOCK = 0x28 -+ AF_WANPIPE = 0x19 -+ AF_X25 = 0x9 -+ AF_XDP = 0x2c -+ ALG_OP_DECRYPT = 0x0 -+ ALG_OP_ENCRYPT = 0x1 -+ ALG_SET_AEAD_ASSOCLEN = 0x4 -+ ALG_SET_AEAD_AUTHSIZE = 0x5 -+ ALG_SET_IV = 0x2 -+ ALG_SET_KEY = 0x1 -+ ALG_SET_OP = 0x3 -+ ANON_INODE_FS_MAGIC = 0x9041934 -+ ARPHRD_6LOWPAN = 0x339 -+ ARPHRD_ADAPT = 0x108 -+ ARPHRD_APPLETLK = 0x8 -+ ARPHRD_ARCNET = 0x7 -+ ARPHRD_ASH = 0x30d -+ ARPHRD_ATM = 0x13 -+ ARPHRD_AX25 = 0x3 -+ ARPHRD_BIF = 0x307 -+ ARPHRD_CAIF = 0x336 -+ ARPHRD_CAN = 0x118 -+ ARPHRD_CHAOS = 0x5 -+ ARPHRD_CISCO = 0x201 -+ ARPHRD_CSLIP = 0x101 -+ ARPHRD_CSLIP6 = 0x103 -+ ARPHRD_DDCMP = 0x205 -+ ARPHRD_DLCI = 0xf -+ ARPHRD_ECONET = 0x30e -+ ARPHRD_EETHER = 0x2 -+ ARPHRD_ETHER = 0x1 -+ ARPHRD_EUI64 = 0x1b -+ ARPHRD_FCAL = 0x311 -+ ARPHRD_FCFABRIC = 0x313 -+ ARPHRD_FCPL = 0x312 -+ ARPHRD_FCPP = 0x310 -+ ARPHRD_FDDI = 0x306 -+ ARPHRD_FRAD = 0x302 -+ ARPHRD_HDLC = 0x201 -+ ARPHRD_HIPPI = 0x30c -+ ARPHRD_HWX25 = 0x110 -+ ARPHRD_IEEE1394 = 0x18 -+ ARPHRD_IEEE802 = 0x6 -+ ARPHRD_IEEE80211 = 0x321 -+ ARPHRD_IEEE80211_PRISM = 0x322 -+ ARPHRD_IEEE80211_RADIOTAP = 0x323 -+ ARPHRD_IEEE802154 = 0x324 -+ ARPHRD_IEEE802154_MONITOR = 0x325 -+ ARPHRD_IEEE802_TR = 0x320 -+ ARPHRD_INFINIBAND = 0x20 -+ ARPHRD_IP6GRE = 0x337 -+ ARPHRD_IPDDP = 0x309 -+ ARPHRD_IPGRE = 0x30a -+ ARPHRD_IRDA = 0x30f -+ ARPHRD_LAPB = 0x204 -+ ARPHRD_LOCALTLK = 0x305 -+ ARPHRD_LOOPBACK = 0x304 -+ ARPHRD_METRICOM = 0x17 -+ ARPHRD_NETLINK = 0x338 -+ ARPHRD_NETROM = 0x0 -+ ARPHRD_NONE = 0xfffe -+ ARPHRD_PHONET = 0x334 -+ ARPHRD_PHONET_PIPE = 0x335 -+ ARPHRD_PIMREG = 0x30b -+ ARPHRD_PPP = 0x200 -+ ARPHRD_PRONET = 0x4 -+ ARPHRD_RAWHDLC = 0x206 -+ ARPHRD_RAWIP = 0x207 -+ ARPHRD_ROSE = 0x10e -+ ARPHRD_RSRVD = 0x104 -+ ARPHRD_SIT = 0x308 -+ ARPHRD_SKIP = 0x303 -+ ARPHRD_SLIP = 0x100 -+ ARPHRD_SLIP6 = 0x102 -+ ARPHRD_TUNNEL = 0x300 -+ ARPHRD_TUNNEL6 = 0x301 -+ ARPHRD_VOID = 0xffff -+ ARPHRD_VSOCKMON = 0x33a -+ ARPHRD_X25 = 0x10f -+ AUTOFS_SUPER_MAGIC = 0x187 -+ B0 = 0x0 -+ B1000000 = 0x1008 -+ B110 = 0x3 -+ B115200 = 0x1002 -+ B1152000 = 0x1009 -+ B1200 = 0x9 -+ B134 = 0x4 -+ B150 = 0x5 -+ B1500000 = 0x100a -+ B1800 = 0xa -+ B19200 = 0xe -+ B200 = 0x6 -+ B2000000 = 0x100b -+ B230400 = 0x1003 -+ B2400 = 0xb -+ B2500000 = 0x100c -+ B300 = 0x7 -+ B3000000 = 0x100d -+ B3500000 = 0x100e -+ B38400 = 0xf -+ B4000000 = 0x100f -+ B460800 = 0x1004 -+ B4800 = 0xc -+ B50 = 0x1 -+ B500000 = 0x1005 -+ B57600 = 0x1001 -+ B576000 = 0x1006 -+ B600 = 0x8 -+ B75 = 0x2 -+ B921600 = 0x1007 -+ B9600 = 0xd -+ BALLOON_KVM_MAGIC = 0x13661366 -+ BDEVFS_MAGIC = 0x62646576 -+ BINFMTFS_MAGIC = 0x42494e4d -+ BLKBSZGET = 0x80081270 -+ BLKBSZSET = 0x40081271 -+ BLKFLSBUF = 0x1261 -+ BLKFRAGET = 0x1265 -+ BLKFRASET = 0x1264 -+ BLKGETSIZE = 0x1260 -+ BLKGETSIZE64 = 0x80081272 -+ BLKPBSZGET = 0x127b -+ BLKRAGET = 0x1263 -+ BLKRASET = 0x1262 -+ BLKROGET = 0x125e -+ BLKROSET = 0x125d -+ BLKRRPART = 0x125f -+ BLKSECTGET = 0x1267 -+ BLKSECTSET = 0x1266 -+ BLKSSZGET = 0x1268 -+ BOTHER = 0x1000 -+ BPF_A = 0x10 -+ BPF_ABS = 0x20 -+ BPF_ADD = 0x0 -+ BPF_ALU = 0x4 -+ BPF_AND = 0x50 -+ BPF_B = 0x10 -+ BPF_DIV = 0x30 -+ BPF_FS_MAGIC = 0xcafe4a11 -+ BPF_H = 0x8 -+ BPF_IMM = 0x0 -+ BPF_IND = 0x40 -+ BPF_JA = 0x0 -+ BPF_JEQ = 0x10 -+ BPF_JGE = 0x30 -+ BPF_JGT = 0x20 -+ BPF_JMP = 0x5 -+ BPF_JSET = 0x40 -+ BPF_K = 0x0 -+ BPF_LD = 0x0 -+ BPF_LDX = 0x1 -+ BPF_LEN = 0x80 -+ BPF_LL_OFF = -0x200000 -+ BPF_LSH = 0x60 -+ BPF_MAJOR_VERSION = 0x1 -+ BPF_MAXINSNS = 0x1000 -+ BPF_MEM = 0x60 -+ BPF_MEMWORDS = 0x10 -+ BPF_MINOR_VERSION = 0x1 -+ BPF_MISC = 0x7 -+ BPF_MOD = 0x90 -+ BPF_MSH = 0xa0 -+ BPF_MUL = 0x20 -+ BPF_NEG = 0x80 -+ BPF_NET_OFF = -0x100000 -+ BPF_OR = 0x40 -+ BPF_RET = 0x6 -+ BPF_RSH = 0x70 -+ BPF_ST = 0x2 -+ BPF_STX = 0x3 -+ BPF_SUB = 0x10 -+ BPF_TAX = 0x0 -+ BPF_TXA = 0x80 -+ BPF_W = 0x0 -+ BPF_X = 0x8 -+ BPF_XOR = 0xa0 -+ BRKINT = 0x2 -+ BS0 = 0x0 -+ BS1 = 0x2000 -+ BSDLY = 0x2000 -+ BTRFS_SUPER_MAGIC = 0x9123683e -+ BTRFS_TEST_MAGIC = 0x73727279 -+ CAN_BCM = 0x2 -+ CAN_EFF_FLAG = 0x80000000 -+ CAN_EFF_ID_BITS = 0x1d -+ CAN_EFF_MASK = 0x1fffffff -+ CAN_ERR_FLAG = 0x20000000 -+ CAN_ERR_MASK = 0x1fffffff -+ CAN_INV_FILTER = 0x20000000 -+ CAN_ISOTP = 0x6 -+ CAN_MAX_DLC = 0x8 -+ CAN_MAX_DLEN = 0x8 -+ CAN_MCNET = 0x5 -+ CAN_MTU = 0x10 -+ CAN_NPROTO = 0x7 -+ CAN_RAW = 0x1 -+ CAN_RAW_FILTER_MAX = 0x200 -+ CAN_RTR_FLAG = 0x40000000 -+ CAN_SFF_ID_BITS = 0xb -+ CAN_SFF_MASK = 0x7ff -+ CAN_TP16 = 0x3 -+ CAN_TP20 = 0x4 -+ CBAUD = 0x100f -+ CBAUDEX = 0x1000 -+ CFLUSH = 0xf -+ CGROUP2_SUPER_MAGIC = 0x63677270 -+ CGROUP_SUPER_MAGIC = 0x27e0eb -+ CIBAUD = 0x100f0000 -+ CLOCAL = 0x800 -+ CLOCK_BOOTTIME = 0x7 -+ CLOCK_BOOTTIME_ALARM = 0x9 -+ CLOCK_DEFAULT = 0x0 -+ CLOCK_EXT = 0x1 -+ CLOCK_INT = 0x2 -+ CLOCK_MONOTONIC = 0x1 -+ CLOCK_MONOTONIC_COARSE = 0x6 -+ CLOCK_MONOTONIC_RAW = 0x4 -+ CLOCK_PROCESS_CPUTIME_ID = 0x2 -+ CLOCK_REALTIME = 0x0 -+ CLOCK_REALTIME_ALARM = 0x8 -+ CLOCK_REALTIME_COARSE = 0x5 -+ CLOCK_TAI = 0xb -+ CLOCK_THREAD_CPUTIME_ID = 0x3 -+ CLOCK_TXFROMRX = 0x4 -+ CLOCK_TXINT = 0x3 -+ CLONE_CHILD_CLEARTID = 0x200000 -+ CLONE_CHILD_SETTID = 0x1000000 -+ CLONE_DETACHED = 0x400000 -+ CLONE_FILES = 0x400 -+ CLONE_FS = 0x200 -+ CLONE_IO = 0x80000000 -+ CLONE_NEWCGROUP = 0x2000000 -+ CLONE_NEWIPC = 0x8000000 -+ CLONE_NEWNET = 0x40000000 -+ CLONE_NEWNS = 0x20000 -+ CLONE_NEWPID = 0x20000000 -+ CLONE_NEWUSER = 0x10000000 -+ CLONE_NEWUTS = 0x4000000 -+ CLONE_PARENT = 0x8000 -+ CLONE_PARENT_SETTID = 0x100000 -+ CLONE_PTRACE = 0x2000 -+ CLONE_SETTLS = 0x80000 -+ CLONE_SIGHAND = 0x800 -+ CLONE_SYSVSEM = 0x40000 -+ CLONE_THREAD = 0x10000 -+ CLONE_UNTRACED = 0x800000 -+ CLONE_VFORK = 0x4000 -+ CLONE_VM = 0x100 -+ CMSPAR = 0x40000000 -+ CODA_SUPER_MAGIC = 0x73757245 -+ CR0 = 0x0 -+ CR1 = 0x200 -+ CR2 = 0x400 -+ CR3 = 0x600 -+ CRAMFS_MAGIC = 0x28cd3d45 -+ CRDLY = 0x600 -+ CREAD = 0x80 -+ CRTSCTS = 0x80000000 -+ CS5 = 0x0 -+ CS6 = 0x10 -+ CS7 = 0x20 -+ CS8 = 0x30 -+ CSIGNAL = 0xff -+ CSIZE = 0x30 -+ CSTART = 0x11 -+ CSTATUS = 0x0 -+ CSTOP = 0x13 -+ CSTOPB = 0x40 -+ CSUSP = 0x1a -+ DAXFS_MAGIC = 0x64646178 -+ DEBUGFS_MAGIC = 0x64626720 -+ DEVPTS_SUPER_MAGIC = 0x1cd1 -+ DT_BLK = 0x6 -+ DT_CHR = 0x2 -+ DT_DIR = 0x4 -+ DT_FIFO = 0x1 -+ DT_LNK = 0xa -+ DT_REG = 0x8 -+ DT_SOCK = 0xc -+ DT_UNKNOWN = 0x0 -+ DT_WHT = 0xe -+ ECHO = 0x8 -+ ECHOCTL = 0x200 -+ ECHOE = 0x10 -+ ECHOK = 0x20 -+ ECHOKE = 0x800 -+ ECHONL = 0x40 -+ ECHOPRT = 0x400 -+ ECRYPTFS_SUPER_MAGIC = 0xf15f -+ EFD_CLOEXEC = 0x80000 -+ EFD_NONBLOCK = 0x800 -+ EFD_SEMAPHORE = 0x1 -+ EFIVARFS_MAGIC = 0xde5e81e4 -+ EFS_SUPER_MAGIC = 0x414a53 -+ ENCODING_DEFAULT = 0x0 -+ ENCODING_FM_MARK = 0x3 -+ ENCODING_FM_SPACE = 0x4 -+ ENCODING_MANCHESTER = 0x5 -+ ENCODING_NRZ = 0x1 -+ ENCODING_NRZI = 0x2 -+ EPOLLERR = 0x8 -+ EPOLLET = 0x80000000 -+ EPOLLEXCLUSIVE = 0x10000000 -+ EPOLLHUP = 0x10 -+ EPOLLIN = 0x1 -+ EPOLLMSG = 0x400 -+ EPOLLONESHOT = 0x40000000 -+ EPOLLOUT = 0x4 -+ EPOLLPRI = 0x2 -+ EPOLLRDBAND = 0x80 -+ EPOLLRDHUP = 0x2000 -+ EPOLLRDNORM = 0x40 -+ EPOLLWAKEUP = 0x20000000 -+ EPOLLWRBAND = 0x200 -+ EPOLLWRNORM = 0x100 -+ EPOLL_CLOEXEC = 0x80000 -+ EPOLL_CTL_ADD = 0x1 -+ EPOLL_CTL_DEL = 0x2 -+ EPOLL_CTL_MOD = 0x3 -+ ETH_P_1588 = 0x88f7 -+ ETH_P_8021AD = 0x88a8 -+ ETH_P_8021AH = 0x88e7 -+ ETH_P_8021Q = 0x8100 -+ ETH_P_80221 = 0x8917 -+ ETH_P_802_2 = 0x4 -+ ETH_P_802_3 = 0x1 -+ ETH_P_802_3_MIN = 0x600 -+ ETH_P_802_EX1 = 0x88b5 -+ ETH_P_AARP = 0x80f3 -+ ETH_P_AF_IUCV = 0xfbfb -+ ETH_P_ALL = 0x3 -+ ETH_P_AOE = 0x88a2 -+ ETH_P_ARCNET = 0x1a -+ ETH_P_ARP = 0x806 -+ ETH_P_ATALK = 0x809b -+ ETH_P_ATMFATE = 0x8884 -+ ETH_P_ATMMPOA = 0x884c -+ ETH_P_AX25 = 0x2 -+ ETH_P_BATMAN = 0x4305 -+ ETH_P_BPQ = 0x8ff -+ ETH_P_CAIF = 0xf7 -+ ETH_P_CAN = 0xc -+ ETH_P_CANFD = 0xd -+ ETH_P_CONTROL = 0x16 -+ ETH_P_CUST = 0x6006 -+ ETH_P_DDCMP = 0x6 -+ ETH_P_DEC = 0x6000 -+ ETH_P_DIAG = 0x6005 -+ ETH_P_DNA_DL = 0x6001 -+ ETH_P_DNA_RC = 0x6002 -+ ETH_P_DNA_RT = 0x6003 -+ ETH_P_DSA = 0x1b -+ ETH_P_ECONET = 0x18 -+ ETH_P_EDSA = 0xdada -+ ETH_P_ERSPAN = 0x88be -+ ETH_P_ERSPAN2 = 0x22eb -+ ETH_P_FCOE = 0x8906 -+ ETH_P_FIP = 0x8914 -+ ETH_P_HDLC = 0x19 -+ ETH_P_HSR = 0x892f -+ ETH_P_IBOE = 0x8915 -+ ETH_P_IEEE802154 = 0xf6 -+ ETH_P_IEEEPUP = 0xa00 -+ ETH_P_IEEEPUPAT = 0xa01 -+ ETH_P_IFE = 0xed3e -+ ETH_P_IP = 0x800 -+ ETH_P_IPV6 = 0x86dd -+ ETH_P_IPX = 0x8137 -+ ETH_P_IRDA = 0x17 -+ ETH_P_LAT = 0x6004 -+ ETH_P_LINK_CTL = 0x886c -+ ETH_P_LOCALTALK = 0x9 -+ ETH_P_LOOP = 0x60 -+ ETH_P_LOOPBACK = 0x9000 -+ ETH_P_MACSEC = 0x88e5 -+ ETH_P_MAP = 0xf9 -+ ETH_P_MOBITEX = 0x15 -+ ETH_P_MPLS_MC = 0x8848 -+ ETH_P_MPLS_UC = 0x8847 -+ ETH_P_MVRP = 0x88f5 -+ ETH_P_NCSI = 0x88f8 -+ ETH_P_NSH = 0x894f -+ ETH_P_PAE = 0x888e -+ ETH_P_PAUSE = 0x8808 -+ ETH_P_PHONET = 0xf5 -+ ETH_P_PPPTALK = 0x10 -+ ETH_P_PPP_DISC = 0x8863 -+ ETH_P_PPP_MP = 0x8 -+ ETH_P_PPP_SES = 0x8864 -+ ETH_P_PREAUTH = 0x88c7 -+ ETH_P_PRP = 0x88fb -+ ETH_P_PUP = 0x200 -+ ETH_P_PUPAT = 0x201 -+ ETH_P_QINQ1 = 0x9100 -+ ETH_P_QINQ2 = 0x9200 -+ ETH_P_QINQ3 = 0x9300 -+ ETH_P_RARP = 0x8035 -+ ETH_P_SCA = 0x6007 -+ ETH_P_SLOW = 0x8809 -+ ETH_P_SNAP = 0x5 -+ ETH_P_TDLS = 0x890d -+ ETH_P_TEB = 0x6558 -+ ETH_P_TIPC = 0x88ca -+ ETH_P_TRAILER = 0x1c -+ ETH_P_TR_802_2 = 0x11 -+ ETH_P_TSN = 0x22f0 -+ ETH_P_WAN_PPP = 0x7 -+ ETH_P_WCCP = 0x883e -+ ETH_P_X25 = 0x805 -+ ETH_P_XDSA = 0xf8 -+ EXABYTE_ENABLE_NEST = 0xf0 -+ EXT2_SUPER_MAGIC = 0xef53 -+ EXT3_SUPER_MAGIC = 0xef53 -+ EXT4_SUPER_MAGIC = 0xef53 -+ EXTA = 0xe -+ EXTB = 0xf -+ EXTPROC = 0x10000 -+ F2FS_SUPER_MAGIC = 0xf2f52010 -+ FALLOC_FL_COLLAPSE_RANGE = 0x8 -+ FALLOC_FL_INSERT_RANGE = 0x20 -+ FALLOC_FL_KEEP_SIZE = 0x1 -+ FALLOC_FL_NO_HIDE_STALE = 0x4 -+ FALLOC_FL_PUNCH_HOLE = 0x2 -+ FALLOC_FL_UNSHARE_RANGE = 0x40 -+ FALLOC_FL_ZERO_RANGE = 0x10 -+ FD_CLOEXEC = 0x1 -+ FD_SETSIZE = 0x400 -+ FF0 = 0x0 -+ FF1 = 0x8000 -+ FFDLY = 0x8000 -+ FLUSHO = 0x1000 -+ FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 -+ FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 -+ FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 -+ FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 -+ FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 -+ FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 -+ FS_ENCRYPTION_MODE_INVALID = 0x0 -+ FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 -+ FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 -+ FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 -+ FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 -+ FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 -+ FS_KEY_DESCRIPTOR_SIZE = 0x8 -+ FS_KEY_DESC_PREFIX = "fscrypt:" -+ FS_KEY_DESC_PREFIX_SIZE = 0x8 -+ FS_MAX_KEY_SIZE = 0x40 -+ FS_POLICY_FLAGS_PAD_16 = 0x2 -+ FS_POLICY_FLAGS_PAD_32 = 0x3 -+ FS_POLICY_FLAGS_PAD_4 = 0x0 -+ FS_POLICY_FLAGS_PAD_8 = 0x1 -+ FS_POLICY_FLAGS_PAD_MASK = 0x3 -+ FS_POLICY_FLAGS_VALID = 0x3 -+ FUTEXFS_SUPER_MAGIC = 0xbad1dea -+ F_ADD_SEALS = 0x409 -+ F_DUPFD = 0x0 -+ F_DUPFD_CLOEXEC = 0x406 -+ F_EXLCK = 0x4 -+ F_GETFD = 0x1 -+ F_GETFL = 0x3 -+ F_GETLEASE = 0x401 -+ F_GETLK = 0x5 -+ F_GETLK64 = 0x5 -+ F_GETOWN = 0x9 -+ F_GETOWN_EX = 0x10 -+ F_GETPIPE_SZ = 0x408 -+ F_GETSIG = 0xb -+ F_GET_FILE_RW_HINT = 0x40d -+ F_GET_RW_HINT = 0x40b -+ F_GET_SEALS = 0x40a -+ F_LOCK = 0x1 -+ F_NOTIFY = 0x402 -+ F_OFD_GETLK = 0x24 -+ F_OFD_SETLK = 0x25 -+ F_OFD_SETLKW = 0x26 -+ F_OK = 0x0 -+ F_RDLCK = 0x0 -+ F_SEAL_GROW = 0x4 -+ F_SEAL_SEAL = 0x1 -+ F_SEAL_SHRINK = 0x2 -+ F_SEAL_WRITE = 0x8 -+ F_SETFD = 0x2 -+ F_SETFL = 0x4 -+ F_SETLEASE = 0x400 -+ F_SETLK = 0x6 -+ F_SETLK64 = 0x6 -+ F_SETLKW = 0x7 -+ F_SETLKW64 = 0x7 -+ F_SETOWN = 0x8 -+ F_SETOWN_EX = 0xf -+ F_SETPIPE_SZ = 0x407 -+ F_SETSIG = 0xa -+ F_SET_FILE_RW_HINT = 0x40e -+ F_SET_RW_HINT = 0x40c -+ F_SHLCK = 0x8 -+ F_TEST = 0x3 -+ F_TLOCK = 0x2 -+ F_ULOCK = 0x0 -+ F_UNLCK = 0x2 -+ F_WRLCK = 0x1 -+ GENL_ADMIN_PERM = 0x1 -+ GENL_CMD_CAP_DO = 0x2 -+ GENL_CMD_CAP_DUMP = 0x4 -+ GENL_CMD_CAP_HASPOL = 0x8 -+ GENL_HDRLEN = 0x4 -+ GENL_ID_CTRL = 0x10 -+ GENL_ID_PMCRAID = 0x12 -+ GENL_ID_VFS_DQUOT = 0x11 -+ GENL_MAX_ID = 0x3ff -+ GENL_MIN_ID = 0x10 -+ GENL_NAMSIZ = 0x10 -+ GENL_START_ALLOC = 0x13 -+ GENL_UNS_ADMIN_PERM = 0x10 -+ GRND_NONBLOCK = 0x1 -+ GRND_RANDOM = 0x2 -+ HDIO_DRIVE_CMD = 0x31f -+ HDIO_DRIVE_CMD_AEB = 0x31e -+ HDIO_DRIVE_CMD_HDR_SIZE = 0x4 -+ HDIO_DRIVE_HOB_HDR_SIZE = 0x8 -+ HDIO_DRIVE_RESET = 0x31c -+ HDIO_DRIVE_TASK = 0x31e -+ HDIO_DRIVE_TASKFILE = 0x31d -+ HDIO_DRIVE_TASK_HDR_SIZE = 0x8 -+ HDIO_GETGEO = 0x301 -+ HDIO_GET_32BIT = 0x309 -+ HDIO_GET_ACOUSTIC = 0x30f -+ HDIO_GET_ADDRESS = 0x310 -+ HDIO_GET_BUSSTATE = 0x31a -+ HDIO_GET_DMA = 0x30b -+ HDIO_GET_IDENTITY = 0x30d -+ HDIO_GET_KEEPSETTINGS = 0x308 -+ HDIO_GET_MULTCOUNT = 0x304 -+ HDIO_GET_NICE = 0x30c -+ HDIO_GET_NOWERR = 0x30a -+ HDIO_GET_QDMA = 0x305 -+ HDIO_GET_UNMASKINTR = 0x302 -+ HDIO_GET_WCACHE = 0x30e -+ HDIO_OBSOLETE_IDENTITY = 0x307 -+ HDIO_SCAN_HWIF = 0x328 -+ HDIO_SET_32BIT = 0x324 -+ HDIO_SET_ACOUSTIC = 0x32c -+ HDIO_SET_ADDRESS = 0x32f -+ HDIO_SET_BUSSTATE = 0x32d -+ HDIO_SET_DMA = 0x326 -+ HDIO_SET_KEEPSETTINGS = 0x323 -+ HDIO_SET_MULTCOUNT = 0x321 -+ HDIO_SET_NICE = 0x329 -+ HDIO_SET_NOWERR = 0x325 -+ HDIO_SET_PIO_MODE = 0x327 -+ HDIO_SET_QDMA = 0x32e -+ HDIO_SET_UNMASKINTR = 0x322 -+ HDIO_SET_WCACHE = 0x32b -+ HDIO_SET_XFER = 0x306 -+ HDIO_TRISTATE_HWIF = 0x31b -+ HDIO_UNREGISTER_HWIF = 0x32a -+ HOSTFS_SUPER_MAGIC = 0xc0ffee -+ HPFS_SUPER_MAGIC = 0xf995e849 -+ HUGETLBFS_MAGIC = 0x958458f6 -+ HUPCL = 0x400 -+ IBSHIFT = 0x10 -+ ICANON = 0x2 -+ ICMPV6_FILTER = 0x1 -+ ICRNL = 0x100 -+ IEXTEN = 0x8000 -+ IFA_F_DADFAILED = 0x8 -+ IFA_F_DEPRECATED = 0x20 -+ IFA_F_HOMEADDRESS = 0x10 -+ IFA_F_MANAGETEMPADDR = 0x100 -+ IFA_F_MCAUTOJOIN = 0x400 -+ IFA_F_NODAD = 0x2 -+ IFA_F_NOPREFIXROUTE = 0x200 -+ IFA_F_OPTIMISTIC = 0x4 -+ IFA_F_PERMANENT = 0x80 -+ IFA_F_SECONDARY = 0x1 -+ IFA_F_STABLE_PRIVACY = 0x800 -+ IFA_F_TEMPORARY = 0x1 -+ IFA_F_TENTATIVE = 0x40 -+ IFA_MAX = 0xa -+ IFF_ALLMULTI = 0x200 -+ IFF_ATTACH_QUEUE = 0x200 -+ IFF_AUTOMEDIA = 0x4000 -+ IFF_BROADCAST = 0x2 -+ IFF_DEBUG = 0x4 -+ IFF_DETACH_QUEUE = 0x400 -+ IFF_DORMANT = 0x20000 -+ IFF_DYNAMIC = 0x8000 -+ IFF_ECHO = 0x40000 -+ IFF_LOOPBACK = 0x8 -+ IFF_LOWER_UP = 0x10000 -+ IFF_MASTER = 0x400 -+ IFF_MULTICAST = 0x1000 -+ IFF_MULTI_QUEUE = 0x100 -+ IFF_NAPI = 0x10 -+ IFF_NAPI_FRAGS = 0x20 -+ IFF_NOARP = 0x80 -+ IFF_NOFILTER = 0x1000 -+ IFF_NOTRAILERS = 0x20 -+ IFF_NO_PI = 0x1000 -+ IFF_ONE_QUEUE = 0x2000 -+ IFF_PERSIST = 0x800 -+ IFF_POINTOPOINT = 0x10 -+ IFF_PORTSEL = 0x2000 -+ IFF_PROMISC = 0x100 -+ IFF_RUNNING = 0x40 -+ IFF_SLAVE = 0x800 -+ IFF_TAP = 0x2 -+ IFF_TUN = 0x1 -+ IFF_TUN_EXCL = 0x8000 -+ IFF_UP = 0x1 -+ IFF_VNET_HDR = 0x4000 -+ IFF_VOLATILE = 0x70c5a -+ IFNAMSIZ = 0x10 -+ IGNBRK = 0x1 -+ IGNCR = 0x80 -+ IGNPAR = 0x4 -+ IMAXBEL = 0x2000 -+ INLCR = 0x40 -+ INPCK = 0x10 -+ IN_ACCESS = 0x1 -+ IN_ALL_EVENTS = 0xfff -+ IN_ATTRIB = 0x4 -+ IN_CLASSA_HOST = 0xffffff -+ IN_CLASSA_MAX = 0x80 -+ IN_CLASSA_NET = 0xff000000 -+ IN_CLASSA_NSHIFT = 0x18 -+ IN_CLASSB_HOST = 0xffff -+ IN_CLASSB_MAX = 0x10000 -+ IN_CLASSB_NET = 0xffff0000 -+ IN_CLASSB_NSHIFT = 0x10 -+ IN_CLASSC_HOST = 0xff -+ IN_CLASSC_NET = 0xffffff00 -+ IN_CLASSC_NSHIFT = 0x8 -+ IN_CLOEXEC = 0x80000 -+ IN_CLOSE = 0x18 -+ IN_CLOSE_NOWRITE = 0x10 -+ IN_CLOSE_WRITE = 0x8 -+ IN_CREATE = 0x100 -+ IN_DELETE = 0x200 -+ IN_DELETE_SELF = 0x400 -+ IN_DONT_FOLLOW = 0x2000000 -+ IN_EXCL_UNLINK = 0x4000000 -+ IN_IGNORED = 0x8000 -+ IN_ISDIR = 0x40000000 -+ IN_LOOPBACKNET = 0x7f -+ IN_MASK_ADD = 0x20000000 -+ IN_MASK_CREATE = 0x10000000 -+ IN_MODIFY = 0x2 -+ IN_MOVE = 0xc0 -+ IN_MOVED_FROM = 0x40 -+ IN_MOVED_TO = 0x80 -+ IN_MOVE_SELF = 0x800 -+ IN_NONBLOCK = 0x800 -+ IN_ONESHOT = 0x80000000 -+ IN_ONLYDIR = 0x1000000 -+ IN_OPEN = 0x20 -+ IN_Q_OVERFLOW = 0x4000 -+ IN_UNMOUNT = 0x2000 -+ IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 -+ IPPROTO_AH = 0x33 -+ IPPROTO_BEETPH = 0x5e -+ IPPROTO_COMP = 0x6c -+ IPPROTO_DCCP = 0x21 -+ IPPROTO_DSTOPTS = 0x3c -+ IPPROTO_EGP = 0x8 -+ IPPROTO_ENCAP = 0x62 -+ IPPROTO_ESP = 0x32 -+ IPPROTO_FRAGMENT = 0x2c -+ IPPROTO_GRE = 0x2f -+ IPPROTO_HOPOPTS = 0x0 -+ IPPROTO_ICMP = 0x1 -+ IPPROTO_ICMPV6 = 0x3a -+ IPPROTO_IDP = 0x16 -+ IPPROTO_IGMP = 0x2 -+ IPPROTO_IP = 0x0 -+ IPPROTO_IPIP = 0x4 -+ IPPROTO_IPV6 = 0x29 -+ IPPROTO_MH = 0x87 -+ IPPROTO_MPLS = 0x89 -+ IPPROTO_MTP = 0x5c -+ IPPROTO_NONE = 0x3b -+ IPPROTO_PIM = 0x67 -+ IPPROTO_PUP = 0xc -+ IPPROTO_RAW = 0xff -+ IPPROTO_ROUTING = 0x2b -+ IPPROTO_RSVP = 0x2e -+ IPPROTO_SCTP = 0x84 -+ IPPROTO_TCP = 0x6 -+ IPPROTO_TP = 0x1d -+ IPPROTO_UDP = 0x11 -+ IPPROTO_UDPLITE = 0x88 -+ IPV6_2292DSTOPTS = 0x4 -+ IPV6_2292HOPLIMIT = 0x8 -+ IPV6_2292HOPOPTS = 0x3 -+ IPV6_2292PKTINFO = 0x2 -+ IPV6_2292PKTOPTIONS = 0x6 -+ IPV6_2292RTHDR = 0x5 -+ IPV6_ADDRFORM = 0x1 -+ IPV6_ADDR_PREFERENCES = 0x48 -+ IPV6_ADD_MEMBERSHIP = 0x14 -+ IPV6_AUTHHDR = 0xa -+ IPV6_AUTOFLOWLABEL = 0x46 -+ IPV6_CHECKSUM = 0x7 -+ IPV6_DONTFRAG = 0x3e -+ IPV6_DROP_MEMBERSHIP = 0x15 -+ IPV6_DSTOPTS = 0x3b -+ IPV6_FREEBIND = 0x4e -+ IPV6_HDRINCL = 0x24 -+ IPV6_HOPLIMIT = 0x34 -+ IPV6_HOPOPTS = 0x36 -+ IPV6_IPSEC_POLICY = 0x22 -+ IPV6_JOIN_ANYCAST = 0x1b -+ IPV6_JOIN_GROUP = 0x14 -+ IPV6_LEAVE_ANYCAST = 0x1c -+ IPV6_LEAVE_GROUP = 0x15 -+ IPV6_MINHOPCOUNT = 0x49 -+ IPV6_MTU = 0x18 -+ IPV6_MTU_DISCOVER = 0x17 -+ IPV6_MULTICAST_ALL = 0x1d -+ IPV6_MULTICAST_HOPS = 0x12 -+ IPV6_MULTICAST_IF = 0x11 -+ IPV6_MULTICAST_LOOP = 0x13 -+ IPV6_NEXTHOP = 0x9 -+ IPV6_ORIGDSTADDR = 0x4a -+ IPV6_PATHMTU = 0x3d -+ IPV6_PKTINFO = 0x32 -+ IPV6_PMTUDISC_DO = 0x2 -+ IPV6_PMTUDISC_DONT = 0x0 -+ IPV6_PMTUDISC_INTERFACE = 0x4 -+ IPV6_PMTUDISC_OMIT = 0x5 -+ IPV6_PMTUDISC_PROBE = 0x3 -+ IPV6_PMTUDISC_WANT = 0x1 -+ IPV6_RECVDSTOPTS = 0x3a -+ IPV6_RECVERR = 0x19 -+ IPV6_RECVFRAGSIZE = 0x4d -+ IPV6_RECVHOPLIMIT = 0x33 -+ IPV6_RECVHOPOPTS = 0x35 -+ IPV6_RECVORIGDSTADDR = 0x4a -+ IPV6_RECVPATHMTU = 0x3c -+ IPV6_RECVPKTINFO = 0x31 -+ IPV6_RECVRTHDR = 0x38 -+ IPV6_RECVTCLASS = 0x42 -+ IPV6_ROUTER_ALERT = 0x16 -+ IPV6_RTHDR = 0x39 -+ IPV6_RTHDRDSTOPTS = 0x37 -+ IPV6_RTHDR_LOOSE = 0x0 -+ IPV6_RTHDR_STRICT = 0x1 -+ IPV6_RTHDR_TYPE_0 = 0x0 -+ IPV6_RXDSTOPTS = 0x3b -+ IPV6_RXHOPOPTS = 0x36 -+ IPV6_TCLASS = 0x43 -+ IPV6_TRANSPARENT = 0x4b -+ IPV6_UNICAST_HOPS = 0x10 -+ IPV6_UNICAST_IF = 0x4c -+ IPV6_V6ONLY = 0x1a -+ IPV6_XFRM_POLICY = 0x23 -+ IP_ADD_MEMBERSHIP = 0x23 -+ IP_ADD_SOURCE_MEMBERSHIP = 0x27 -+ IP_BIND_ADDRESS_NO_PORT = 0x18 -+ IP_BLOCK_SOURCE = 0x26 -+ IP_CHECKSUM = 0x17 -+ IP_DEFAULT_MULTICAST_LOOP = 0x1 -+ IP_DEFAULT_MULTICAST_TTL = 0x1 -+ IP_DF = 0x4000 -+ IP_DROP_MEMBERSHIP = 0x24 -+ IP_DROP_SOURCE_MEMBERSHIP = 0x28 -+ IP_FREEBIND = 0xf -+ IP_HDRINCL = 0x3 -+ IP_IPSEC_POLICY = 0x10 -+ IP_MAXPACKET = 0xffff -+ IP_MAX_MEMBERSHIPS = 0x14 -+ IP_MF = 0x2000 -+ IP_MINTTL = 0x15 -+ IP_MSFILTER = 0x29 -+ IP_MSS = 0x240 -+ IP_MTU = 0xe -+ IP_MTU_DISCOVER = 0xa -+ IP_MULTICAST_ALL = 0x31 -+ IP_MULTICAST_IF = 0x20 -+ IP_MULTICAST_LOOP = 0x22 -+ IP_MULTICAST_TTL = 0x21 -+ IP_NODEFRAG = 0x16 -+ IP_OFFMASK = 0x1fff -+ IP_OPTIONS = 0x4 -+ IP_ORIGDSTADDR = 0x14 -+ IP_PASSSEC = 0x12 -+ IP_PKTINFO = 0x8 -+ IP_PKTOPTIONS = 0x9 -+ IP_PMTUDISC = 0xa -+ IP_PMTUDISC_DO = 0x2 -+ IP_PMTUDISC_DONT = 0x0 -+ IP_PMTUDISC_INTERFACE = 0x4 -+ IP_PMTUDISC_OMIT = 0x5 -+ IP_PMTUDISC_PROBE = 0x3 -+ IP_PMTUDISC_WANT = 0x1 -+ IP_RECVERR = 0xb -+ IP_RECVFRAGSIZE = 0x19 -+ IP_RECVOPTS = 0x6 -+ IP_RECVORIGDSTADDR = 0x14 -+ IP_RECVRETOPTS = 0x7 -+ IP_RECVTOS = 0xd -+ IP_RECVTTL = 0xc -+ IP_RETOPTS = 0x7 -+ IP_RF = 0x8000 -+ IP_ROUTER_ALERT = 0x5 -+ IP_TOS = 0x1 -+ IP_TRANSPARENT = 0x13 -+ IP_TTL = 0x2 -+ IP_UNBLOCK_SOURCE = 0x25 -+ IP_UNICAST_IF = 0x32 -+ IP_XFRM_POLICY = 0x11 -+ ISIG = 0x1 -+ ISOFS_SUPER_MAGIC = 0x9660 -+ ISTRIP = 0x20 -+ IUCLC = 0x200 -+ IUTF8 = 0x4000 -+ IXANY = 0x800 -+ IXOFF = 0x1000 -+ IXON = 0x400 -+ JFFS2_SUPER_MAGIC = 0x72b6 -+ KEXEC_ARCH_386 = 0x30000 -+ KEXEC_ARCH_68K = 0x40000 -+ KEXEC_ARCH_AARCH64 = 0xb70000 -+ KEXEC_ARCH_ARM = 0x280000 -+ KEXEC_ARCH_DEFAULT = 0x0 -+ KEXEC_ARCH_IA_64 = 0x320000 -+ KEXEC_ARCH_MASK = 0xffff0000 -+ KEXEC_ARCH_MIPS = 0x80000 -+ KEXEC_ARCH_MIPS_LE = 0xa0000 -+ KEXEC_ARCH_PPC = 0x140000 -+ KEXEC_ARCH_PPC64 = 0x150000 -+ KEXEC_ARCH_S390 = 0x160000 -+ KEXEC_ARCH_SH = 0x2a0000 -+ KEXEC_ARCH_X86_64 = 0x3e0000 -+ KEXEC_FILE_NO_INITRAMFS = 0x4 -+ KEXEC_FILE_ON_CRASH = 0x2 -+ KEXEC_FILE_UNLOAD = 0x1 -+ KEXEC_ON_CRASH = 0x1 -+ KEXEC_PRESERVE_CONTEXT = 0x2 -+ KEXEC_SEGMENT_MAX = 0x10 -+ KEYCTL_ASSUME_AUTHORITY = 0x10 -+ KEYCTL_CHOWN = 0x4 -+ KEYCTL_CLEAR = 0x7 -+ KEYCTL_DESCRIBE = 0x6 -+ KEYCTL_DH_COMPUTE = 0x17 -+ KEYCTL_GET_KEYRING_ID = 0x0 -+ KEYCTL_GET_PERSISTENT = 0x16 -+ KEYCTL_GET_SECURITY = 0x11 -+ KEYCTL_INSTANTIATE = 0xc -+ KEYCTL_INSTANTIATE_IOV = 0x14 -+ KEYCTL_INVALIDATE = 0x15 -+ KEYCTL_JOIN_SESSION_KEYRING = 0x1 -+ KEYCTL_LINK = 0x8 -+ KEYCTL_NEGATE = 0xd -+ KEYCTL_PKEY_DECRYPT = 0x1a -+ KEYCTL_PKEY_ENCRYPT = 0x19 -+ KEYCTL_PKEY_QUERY = 0x18 -+ KEYCTL_PKEY_SIGN = 0x1b -+ KEYCTL_PKEY_VERIFY = 0x1c -+ KEYCTL_READ = 0xb -+ KEYCTL_REJECT = 0x13 -+ KEYCTL_RESTRICT_KEYRING = 0x1d -+ KEYCTL_REVOKE = 0x3 -+ KEYCTL_SEARCH = 0xa -+ KEYCTL_SESSION_TO_PARENT = 0x12 -+ KEYCTL_SETPERM = 0x5 -+ KEYCTL_SET_REQKEY_KEYRING = 0xe -+ KEYCTL_SET_TIMEOUT = 0xf -+ KEYCTL_SUPPORTS_DECRYPT = 0x2 -+ KEYCTL_SUPPORTS_ENCRYPT = 0x1 -+ KEYCTL_SUPPORTS_SIGN = 0x4 -+ KEYCTL_SUPPORTS_VERIFY = 0x8 -+ KEYCTL_UNLINK = 0x9 -+ KEYCTL_UPDATE = 0x2 -+ KEY_REQKEY_DEFL_DEFAULT = 0x0 -+ KEY_REQKEY_DEFL_GROUP_KEYRING = 0x6 -+ KEY_REQKEY_DEFL_NO_CHANGE = -0x1 -+ KEY_REQKEY_DEFL_PROCESS_KEYRING = 0x2 -+ KEY_REQKEY_DEFL_REQUESTOR_KEYRING = 0x7 -+ KEY_REQKEY_DEFL_SESSION_KEYRING = 0x3 -+ KEY_REQKEY_DEFL_THREAD_KEYRING = 0x1 -+ KEY_REQKEY_DEFL_USER_KEYRING = 0x4 -+ KEY_REQKEY_DEFL_USER_SESSION_KEYRING = 0x5 -+ KEY_SPEC_GROUP_KEYRING = -0x6 -+ KEY_SPEC_PROCESS_KEYRING = -0x2 -+ KEY_SPEC_REQKEY_AUTH_KEY = -0x7 -+ KEY_SPEC_REQUESTOR_KEYRING = -0x8 -+ KEY_SPEC_SESSION_KEYRING = -0x3 -+ KEY_SPEC_THREAD_KEYRING = -0x1 -+ KEY_SPEC_USER_KEYRING = -0x4 -+ KEY_SPEC_USER_SESSION_KEYRING = -0x5 -+ LINUX_REBOOT_CMD_CAD_OFF = 0x0 -+ LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef -+ LINUX_REBOOT_CMD_HALT = 0xcdef0123 -+ LINUX_REBOOT_CMD_KEXEC = 0x45584543 -+ LINUX_REBOOT_CMD_POWER_OFF = 0x4321fedc -+ LINUX_REBOOT_CMD_RESTART = 0x1234567 -+ LINUX_REBOOT_CMD_RESTART2 = 0xa1b2c3d4 -+ LINUX_REBOOT_CMD_SW_SUSPEND = 0xd000fce2 -+ LINUX_REBOOT_MAGIC1 = 0xfee1dead -+ LINUX_REBOOT_MAGIC2 = 0x28121969 -+ LOCK_EX = 0x2 -+ LOCK_NB = 0x4 -+ LOCK_SH = 0x1 -+ LOCK_UN = 0x8 -+ MADV_DODUMP = 0x11 -+ MADV_DOFORK = 0xb -+ MADV_DONTDUMP = 0x10 -+ MADV_DONTFORK = 0xa -+ MADV_DONTNEED = 0x4 -+ MADV_FREE = 0x8 -+ MADV_HUGEPAGE = 0xe -+ MADV_HWPOISON = 0x64 -+ MADV_KEEPONFORK = 0x13 -+ MADV_MERGEABLE = 0xc -+ MADV_NOHUGEPAGE = 0xf -+ MADV_NORMAL = 0x0 -+ MADV_RANDOM = 0x1 -+ MADV_REMOVE = 0x9 -+ MADV_SEQUENTIAL = 0x2 -+ MADV_UNMERGEABLE = 0xd -+ MADV_WILLNEED = 0x3 -+ MADV_WIPEONFORK = 0x12 -+ MAP_ANON = 0x20 -+ MAP_ANONYMOUS = 0x20 -+ MAP_DENYWRITE = 0x800 -+ MAP_EXECUTABLE = 0x1000 -+ MAP_FILE = 0x0 -+ MAP_FIXED = 0x10 -+ MAP_FIXED_NOREPLACE = 0x100000 -+ MAP_GROWSDOWN = 0x100 -+ MAP_HUGETLB = 0x40000 -+ MAP_HUGE_MASK = 0x3f -+ MAP_HUGE_SHIFT = 0x1a -+ MAP_LOCKED = 0x2000 -+ MAP_NONBLOCK = 0x10000 -+ MAP_NORESERVE = 0x4000 -+ MAP_POPULATE = 0x8000 -+ MAP_PRIVATE = 0x2 -+ MAP_SHARED = 0x1 -+ MAP_SHARED_VALIDATE = 0x3 -+ MAP_STACK = 0x20000 -+ MAP_SYNC = 0x80000 -+ MAP_TYPE = 0xf -+ MCL_CURRENT = 0x1 -+ MCL_FUTURE = 0x2 -+ MCL_ONFAULT = 0x4 -+ MFD_ALLOW_SEALING = 0x2 -+ MFD_CLOEXEC = 0x1 -+ MFD_HUGETLB = 0x4 -+ MFD_HUGE_16GB = -0x78000000 -+ MFD_HUGE_16MB = 0x60000000 -+ MFD_HUGE_1GB = 0x78000000 -+ MFD_HUGE_1MB = 0x50000000 -+ MFD_HUGE_256MB = 0x70000000 -+ MFD_HUGE_2GB = 0x7c000000 -+ MFD_HUGE_2MB = 0x54000000 -+ MFD_HUGE_32MB = 0x64000000 -+ MFD_HUGE_512KB = 0x4c000000 -+ MFD_HUGE_512MB = 0x74000000 -+ MFD_HUGE_64KB = 0x40000000 -+ MFD_HUGE_8MB = 0x5c000000 -+ MFD_HUGE_MASK = 0x3f -+ MFD_HUGE_SHIFT = 0x1a -+ MINIX2_SUPER_MAGIC = 0x2468 -+ MINIX2_SUPER_MAGIC2 = 0x2478 -+ MINIX3_SUPER_MAGIC = 0x4d5a -+ MINIX_SUPER_MAGIC = 0x137f -+ MINIX_SUPER_MAGIC2 = 0x138f -+ MNT_DETACH = 0x2 -+ MNT_EXPIRE = 0x4 -+ MNT_FORCE = 0x1 -+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1 -+ MODULE_INIT_IGNORE_VERMAGIC = 0x2 -+ MSDOS_SUPER_MAGIC = 0x4d44 -+ MSG_BATCH = 0x40000 -+ MSG_CMSG_CLOEXEC = 0x40000000 -+ MSG_CONFIRM = 0x800 -+ MSG_CTRUNC = 0x8 -+ MSG_DONTROUTE = 0x4 -+ MSG_DONTWAIT = 0x40 -+ MSG_EOR = 0x80 -+ MSG_ERRQUEUE = 0x2000 -+ MSG_FASTOPEN = 0x20000000 -+ MSG_FIN = 0x200 -+ MSG_MORE = 0x8000 -+ MSG_NOSIGNAL = 0x4000 -+ MSG_OOB = 0x1 -+ MSG_PEEK = 0x2 -+ MSG_PROXY = 0x10 -+ MSG_RST = 0x1000 -+ MSG_SYN = 0x400 -+ MSG_TRUNC = 0x20 -+ MSG_TRYHARD = 0x4 -+ MSG_WAITALL = 0x100 -+ MSG_WAITFORONE = 0x10000 -+ MSG_ZEROCOPY = 0x4000000 -+ MS_ACTIVE = 0x40000000 -+ MS_ASYNC = 0x1 -+ MS_BIND = 0x1000 -+ MS_BORN = 0x20000000 -+ MS_DIRSYNC = 0x80 -+ MS_INVALIDATE = 0x2 -+ MS_I_VERSION = 0x800000 -+ MS_KERNMOUNT = 0x400000 -+ MS_LAZYTIME = 0x2000000 -+ MS_MANDLOCK = 0x40 -+ MS_MGC_MSK = 0xffff0000 -+ MS_MGC_VAL = 0xc0ed0000 -+ MS_MOVE = 0x2000 -+ MS_NOATIME = 0x400 -+ MS_NODEV = 0x4 -+ MS_NODIRATIME = 0x800 -+ MS_NOEXEC = 0x8 -+ MS_NOREMOTELOCK = 0x8000000 -+ MS_NOSEC = 0x10000000 -+ MS_NOSUID = 0x2 -+ MS_NOUSER = -0x80000000 -+ MS_POSIXACL = 0x10000 -+ MS_PRIVATE = 0x40000 -+ MS_RDONLY = 0x1 -+ MS_REC = 0x4000 -+ MS_RELATIME = 0x200000 -+ MS_REMOUNT = 0x20 -+ MS_RMT_MASK = 0x2800051 -+ MS_SHARED = 0x100000 -+ MS_SILENT = 0x8000 -+ MS_SLAVE = 0x80000 -+ MS_STRICTATIME = 0x1000000 -+ MS_SUBMOUNT = 0x4000000 -+ MS_SYNC = 0x4 -+ MS_SYNCHRONOUS = 0x10 -+ MS_UNBINDABLE = 0x20000 -+ MS_VERBOSE = 0x8000 -+ MTD_INODE_FS_MAGIC = 0x11307854 -+ NAME_MAX = 0xff -+ NCP_SUPER_MAGIC = 0x564c -+ NETLINK_ADD_MEMBERSHIP = 0x1 -+ NETLINK_AUDIT = 0x9 -+ NETLINK_BROADCAST_ERROR = 0x4 -+ NETLINK_CAP_ACK = 0xa -+ NETLINK_CONNECTOR = 0xb -+ NETLINK_CRYPTO = 0x15 -+ NETLINK_DNRTMSG = 0xe -+ NETLINK_DROP_MEMBERSHIP = 0x2 -+ NETLINK_ECRYPTFS = 0x13 -+ NETLINK_EXT_ACK = 0xb -+ NETLINK_FIB_LOOKUP = 0xa -+ NETLINK_FIREWALL = 0x3 -+ NETLINK_GENERIC = 0x10 -+ NETLINK_GET_STRICT_CHK = 0xc -+ NETLINK_INET_DIAG = 0x4 -+ NETLINK_IP6_FW = 0xd -+ NETLINK_ISCSI = 0x8 -+ NETLINK_KOBJECT_UEVENT = 0xf -+ NETLINK_LISTEN_ALL_NSID = 0x8 -+ NETLINK_LIST_MEMBERSHIPS = 0x9 -+ NETLINK_NETFILTER = 0xc -+ NETLINK_NFLOG = 0x5 -+ NETLINK_NO_ENOBUFS = 0x5 -+ NETLINK_PKTINFO = 0x3 -+ NETLINK_RDMA = 0x14 -+ NETLINK_ROUTE = 0x0 -+ NETLINK_RX_RING = 0x6 -+ NETLINK_SCSITRANSPORT = 0x12 -+ NETLINK_SELINUX = 0x7 -+ NETLINK_SMC = 0x16 -+ NETLINK_SOCK_DIAG = 0x4 -+ NETLINK_TX_RING = 0x7 -+ NETLINK_UNUSED = 0x1 -+ NETLINK_USERSOCK = 0x2 -+ NETLINK_XFRM = 0x6 -+ NETNSA_MAX = 0x3 -+ NETNSA_NSID_NOT_ASSIGNED = -0x1 -+ NFNETLINK_V0 = 0x0 -+ NFNLGRP_ACCT_QUOTA = 0x8 -+ NFNLGRP_CONNTRACK_DESTROY = 0x3 -+ NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 -+ NFNLGRP_CONNTRACK_EXP_NEW = 0x4 -+ NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 -+ NFNLGRP_CONNTRACK_NEW = 0x1 -+ NFNLGRP_CONNTRACK_UPDATE = 0x2 -+ NFNLGRP_MAX = 0x9 -+ NFNLGRP_NFTABLES = 0x7 -+ NFNLGRP_NFTRACE = 0x9 -+ NFNLGRP_NONE = 0x0 -+ NFNL_BATCH_MAX = 0x1 -+ NFNL_MSG_BATCH_BEGIN = 0x10 -+ NFNL_MSG_BATCH_END = 0x11 -+ NFNL_NFA_NEST = 0x8000 -+ NFNL_SUBSYS_ACCT = 0x7 -+ NFNL_SUBSYS_COUNT = 0xc -+ NFNL_SUBSYS_CTHELPER = 0x9 -+ NFNL_SUBSYS_CTNETLINK = 0x1 -+ NFNL_SUBSYS_CTNETLINK_EXP = 0x2 -+ NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 -+ NFNL_SUBSYS_IPSET = 0x6 -+ NFNL_SUBSYS_NFTABLES = 0xa -+ NFNL_SUBSYS_NFT_COMPAT = 0xb -+ NFNL_SUBSYS_NONE = 0x0 -+ NFNL_SUBSYS_OSF = 0x5 -+ NFNL_SUBSYS_QUEUE = 0x3 -+ NFNL_SUBSYS_ULOG = 0x4 -+ NFS_SUPER_MAGIC = 0x6969 -+ NILFS_SUPER_MAGIC = 0x3434 -+ NL0 = 0x0 -+ NL1 = 0x100 -+ NLA_ALIGNTO = 0x4 -+ NLA_F_NESTED = 0x8000 -+ NLA_F_NET_BYTEORDER = 0x4000 -+ NLA_HDRLEN = 0x4 -+ NLDLY = 0x100 -+ NLMSG_ALIGNTO = 0x4 -+ NLMSG_DONE = 0x3 -+ NLMSG_ERROR = 0x2 -+ NLMSG_HDRLEN = 0x10 -+ NLMSG_MIN_TYPE = 0x10 -+ NLMSG_NOOP = 0x1 -+ NLMSG_OVERRUN = 0x4 -+ NLM_F_ACK = 0x4 -+ NLM_F_ACK_TLVS = 0x200 -+ NLM_F_APPEND = 0x800 -+ NLM_F_ATOMIC = 0x400 -+ NLM_F_CAPPED = 0x100 -+ NLM_F_CREATE = 0x400 -+ NLM_F_DUMP = 0x300 -+ NLM_F_DUMP_FILTERED = 0x20 -+ NLM_F_DUMP_INTR = 0x10 -+ NLM_F_ECHO = 0x8 -+ NLM_F_EXCL = 0x200 -+ NLM_F_MATCH = 0x200 -+ NLM_F_MULTI = 0x2 -+ NLM_F_NONREC = 0x100 -+ NLM_F_REPLACE = 0x100 -+ NLM_F_REQUEST = 0x1 -+ NLM_F_ROOT = 0x100 -+ NOFLSH = 0x80 -+ NSFS_MAGIC = 0x6e736673 -+ OCFS2_SUPER_MAGIC = 0x7461636f -+ OCRNL = 0x8 -+ OFDEL = 0x80 -+ OFILL = 0x40 -+ OLCUC = 0x2 -+ ONLCR = 0x4 -+ ONLRET = 0x20 -+ ONOCR = 0x10 -+ OPENPROM_SUPER_MAGIC = 0x9fa1 -+ OPOST = 0x1 -+ OVERLAYFS_SUPER_MAGIC = 0x794c7630 -+ O_ACCMODE = 0x3 -+ O_APPEND = 0x400 -+ O_ASYNC = 0x2000 -+ O_CLOEXEC = 0x80000 -+ O_CREAT = 0x40 -+ O_DIRECT = 0x4000 -+ O_DIRECTORY = 0x10000 -+ O_DSYNC = 0x1000 -+ O_EXCL = 0x80 -+ O_FSYNC = 0x101000 -+ O_LARGEFILE = 0x0 -+ O_NDELAY = 0x800 -+ O_NOATIME = 0x40000 -+ O_NOCTTY = 0x100 -+ O_NOFOLLOW = 0x20000 -+ O_NONBLOCK = 0x800 -+ O_PATH = 0x200000 -+ O_RDONLY = 0x0 -+ O_RDWR = 0x2 -+ O_RSYNC = 0x101000 -+ O_SYNC = 0x101000 -+ O_TMPFILE = 0x410000 -+ O_TRUNC = 0x200 -+ O_WRONLY = 0x1 -+ PACKET_ADD_MEMBERSHIP = 0x1 -+ PACKET_AUXDATA = 0x8 -+ PACKET_BROADCAST = 0x1 -+ PACKET_COPY_THRESH = 0x7 -+ PACKET_DROP_MEMBERSHIP = 0x2 -+ PACKET_FANOUT = 0x12 -+ PACKET_FANOUT_CBPF = 0x6 -+ PACKET_FANOUT_CPU = 0x2 -+ PACKET_FANOUT_DATA = 0x16 -+ PACKET_FANOUT_EBPF = 0x7 -+ PACKET_FANOUT_FLAG_DEFRAG = 0x8000 -+ PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 -+ PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 -+ PACKET_FANOUT_HASH = 0x0 -+ PACKET_FANOUT_LB = 0x1 -+ PACKET_FANOUT_QM = 0x5 -+ PACKET_FANOUT_RND = 0x4 -+ PACKET_FANOUT_ROLLOVER = 0x3 -+ PACKET_FASTROUTE = 0x6 -+ PACKET_HDRLEN = 0xb -+ PACKET_HOST = 0x0 -+ PACKET_IGNORE_OUTGOING = 0x17 -+ PACKET_KERNEL = 0x7 -+ PACKET_LOOPBACK = 0x5 -+ PACKET_LOSS = 0xe -+ PACKET_MR_ALLMULTI = 0x2 -+ PACKET_MR_MULTICAST = 0x0 -+ PACKET_MR_PROMISC = 0x1 -+ PACKET_MR_UNICAST = 0x3 -+ PACKET_MULTICAST = 0x2 -+ PACKET_ORIGDEV = 0x9 -+ PACKET_OTHERHOST = 0x3 -+ PACKET_OUTGOING = 0x4 -+ PACKET_QDISC_BYPASS = 0x14 -+ PACKET_RECV_OUTPUT = 0x3 -+ PACKET_RESERVE = 0xc -+ PACKET_ROLLOVER_STATS = 0x15 -+ PACKET_RX_RING = 0x5 -+ PACKET_STATISTICS = 0x6 -+ PACKET_TIMESTAMP = 0x11 -+ PACKET_TX_HAS_OFF = 0x13 -+ PACKET_TX_RING = 0xd -+ PACKET_TX_TIMESTAMP = 0x10 -+ PACKET_USER = 0x6 -+ PACKET_VERSION = 0xa -+ PACKET_VNET_HDR = 0xf -+ PARENB = 0x100 -+ PARITY_CRC16_PR0 = 0x2 -+ PARITY_CRC16_PR0_CCITT = 0x4 -+ PARITY_CRC16_PR1 = 0x3 -+ PARITY_CRC16_PR1_CCITT = 0x5 -+ PARITY_CRC32_PR0_CCITT = 0x6 -+ PARITY_CRC32_PR1_CCITT = 0x7 -+ PARITY_DEFAULT = 0x0 -+ PARITY_NONE = 0x1 -+ PARMRK = 0x8 -+ PARODD = 0x200 -+ PENDIN = 0x4000 -+ PERF_EVENT_IOC_DISABLE = 0x2401 -+ PERF_EVENT_IOC_ENABLE = 0x2400 -+ PERF_EVENT_IOC_ID = 0x80082407 -+ PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x4008240b -+ PERF_EVENT_IOC_PAUSE_OUTPUT = 0x40042409 -+ PERF_EVENT_IOC_PERIOD = 0x40082404 -+ PERF_EVENT_IOC_QUERY_BPF = 0xc008240a -+ PERF_EVENT_IOC_REFRESH = 0x2402 -+ PERF_EVENT_IOC_RESET = 0x2403 -+ PERF_EVENT_IOC_SET_BPF = 0x40042408 -+ PERF_EVENT_IOC_SET_FILTER = 0x40082406 -+ PERF_EVENT_IOC_SET_OUTPUT = 0x2405 -+ PIPEFS_MAGIC = 0x50495045 -+ PPPIOCATTACH = 0x4004743d -+ PPPIOCATTCHAN = 0x40047438 -+ PPPIOCCONNECT = 0x4004743a -+ PPPIOCDETACH = 0x4004743c -+ PPPIOCDISCONN = 0x7439 -+ PPPIOCGASYNCMAP = 0x80047458 -+ PPPIOCGCHAN = 0x80047437 -+ PPPIOCGDEBUG = 0x80047441 -+ PPPIOCGFLAGS = 0x8004745a -+ PPPIOCGIDLE = 0x8010743f -+ PPPIOCGL2TPSTATS = 0x80487436 -+ PPPIOCGMRU = 0x80047453 -+ PPPIOCGNPMODE = 0xc008744c -+ PPPIOCGRASYNCMAP = 0x80047455 -+ PPPIOCGUNIT = 0x80047456 -+ PPPIOCGXASYNCMAP = 0x80207450 -+ PPPIOCNEWUNIT = 0xc004743e -+ PPPIOCSACTIVE = 0x40107446 -+ PPPIOCSASYNCMAP = 0x40047457 -+ PPPIOCSCOMPRESS = 0x4010744d -+ PPPIOCSDEBUG = 0x40047440 -+ PPPIOCSFLAGS = 0x40047459 -+ PPPIOCSMAXCID = 0x40047451 -+ PPPIOCSMRRU = 0x4004743b -+ PPPIOCSMRU = 0x40047452 -+ PPPIOCSNPMODE = 0x4008744b -+ PPPIOCSPASS = 0x40107447 -+ PPPIOCSRASYNCMAP = 0x40047454 -+ PPPIOCSXASYNCMAP = 0x4020744f -+ PPPIOCXFERUNIT = 0x744e -+ PRIO_PGRP = 0x1 -+ PRIO_PROCESS = 0x0 -+ PRIO_USER = 0x2 -+ PROC_SUPER_MAGIC = 0x9fa0 -+ PROT_EXEC = 0x4 -+ PROT_GROWSDOWN = 0x1000000 -+ PROT_GROWSUP = 0x2000000 -+ PROT_NONE = 0x0 -+ PROT_READ = 0x1 -+ PROT_WRITE = 0x2 -+ PR_CAPBSET_DROP = 0x18 -+ PR_CAPBSET_READ = 0x17 -+ PR_CAP_AMBIENT = 0x2f -+ PR_CAP_AMBIENT_CLEAR_ALL = 0x4 -+ PR_CAP_AMBIENT_IS_SET = 0x1 -+ PR_CAP_AMBIENT_LOWER = 0x3 -+ PR_CAP_AMBIENT_RAISE = 0x2 -+ PR_ENDIAN_BIG = 0x0 -+ PR_ENDIAN_LITTLE = 0x1 -+ PR_ENDIAN_PPC_LITTLE = 0x2 -+ PR_FPEMU_NOPRINT = 0x1 -+ PR_FPEMU_SIGFPE = 0x2 -+ PR_FP_EXC_ASYNC = 0x2 -+ PR_FP_EXC_DISABLED = 0x0 -+ PR_FP_EXC_DIV = 0x10000 -+ PR_FP_EXC_INV = 0x100000 -+ PR_FP_EXC_NONRECOV = 0x1 -+ PR_FP_EXC_OVF = 0x20000 -+ PR_FP_EXC_PRECISE = 0x3 -+ PR_FP_EXC_RES = 0x80000 -+ PR_FP_EXC_SW_ENABLE = 0x80 -+ PR_FP_EXC_UND = 0x40000 -+ PR_FP_MODE_FR = 0x1 -+ PR_FP_MODE_FRE = 0x2 -+ PR_GET_CHILD_SUBREAPER = 0x25 -+ PR_GET_DUMPABLE = 0x3 -+ PR_GET_ENDIAN = 0x13 -+ PR_GET_FPEMU = 0x9 -+ PR_GET_FPEXC = 0xb -+ PR_GET_FP_MODE = 0x2e -+ PR_GET_KEEPCAPS = 0x7 -+ PR_GET_NAME = 0x10 -+ PR_GET_NO_NEW_PRIVS = 0x27 -+ PR_GET_PDEATHSIG = 0x2 -+ PR_GET_SECCOMP = 0x15 -+ PR_GET_SECUREBITS = 0x1b -+ PR_GET_SPECULATION_CTRL = 0x34 -+ PR_GET_THP_DISABLE = 0x2a -+ PR_GET_TID_ADDRESS = 0x28 -+ PR_GET_TIMERSLACK = 0x1e -+ PR_GET_TIMING = 0xd -+ PR_GET_TSC = 0x19 -+ PR_GET_UNALIGN = 0x5 -+ PR_MCE_KILL = 0x21 -+ PR_MCE_KILL_CLEAR = 0x0 -+ PR_MCE_KILL_DEFAULT = 0x2 -+ PR_MCE_KILL_EARLY = 0x1 -+ PR_MCE_KILL_GET = 0x22 -+ PR_MCE_KILL_LATE = 0x0 -+ PR_MCE_KILL_SET = 0x1 -+ PR_MPX_DISABLE_MANAGEMENT = 0x2c -+ PR_MPX_ENABLE_MANAGEMENT = 0x2b -+ PR_SET_CHILD_SUBREAPER = 0x24 -+ PR_SET_DUMPABLE = 0x4 -+ PR_SET_ENDIAN = 0x14 -+ PR_SET_FPEMU = 0xa -+ PR_SET_FPEXC = 0xc -+ PR_SET_FP_MODE = 0x2d -+ PR_SET_KEEPCAPS = 0x8 -+ PR_SET_MM = 0x23 -+ PR_SET_MM_ARG_END = 0x9 -+ PR_SET_MM_ARG_START = 0x8 -+ PR_SET_MM_AUXV = 0xc -+ PR_SET_MM_BRK = 0x7 -+ PR_SET_MM_END_CODE = 0x2 -+ PR_SET_MM_END_DATA = 0x4 -+ PR_SET_MM_ENV_END = 0xb -+ PR_SET_MM_ENV_START = 0xa -+ PR_SET_MM_EXE_FILE = 0xd -+ PR_SET_MM_MAP = 0xe -+ PR_SET_MM_MAP_SIZE = 0xf -+ PR_SET_MM_START_BRK = 0x6 -+ PR_SET_MM_START_CODE = 0x1 -+ PR_SET_MM_START_DATA = 0x3 -+ PR_SET_MM_START_STACK = 0x5 -+ PR_SET_NAME = 0xf -+ PR_SET_NO_NEW_PRIVS = 0x26 -+ PR_SET_PDEATHSIG = 0x1 -+ PR_SET_PTRACER = 0x59616d61 -+ PR_SET_PTRACER_ANY = 0xffffffffffffffff -+ PR_SET_SECCOMP = 0x16 -+ PR_SET_SECUREBITS = 0x1c -+ PR_SET_SPECULATION_CTRL = 0x35 -+ PR_SET_THP_DISABLE = 0x29 -+ PR_SET_TIMERSLACK = 0x1d -+ PR_SET_TIMING = 0xe -+ PR_SET_TSC = 0x1a -+ PR_SET_UNALIGN = 0x6 -+ PR_SPEC_DISABLE = 0x4 -+ PR_SPEC_ENABLE = 0x2 -+ PR_SPEC_FORCE_DISABLE = 0x8 -+ PR_SPEC_INDIRECT_BRANCH = 0x1 -+ PR_SPEC_NOT_AFFECTED = 0x0 -+ PR_SPEC_PRCTL = 0x1 -+ PR_SPEC_STORE_BYPASS = 0x0 -+ PR_SVE_GET_VL = 0x33 -+ PR_SVE_SET_VL = 0x32 -+ PR_SVE_SET_VL_ONEXEC = 0x40000 -+ PR_SVE_VL_INHERIT = 0x20000 -+ PR_SVE_VL_LEN_MASK = 0xffff -+ PR_TASK_PERF_EVENTS_DISABLE = 0x1f -+ PR_TASK_PERF_EVENTS_ENABLE = 0x20 -+ PR_TIMING_STATISTICAL = 0x0 -+ PR_TIMING_TIMESTAMP = 0x1 -+ PR_TSC_ENABLE = 0x1 -+ PR_TSC_SIGSEGV = 0x2 -+ PR_UNALIGN_NOPRINT = 0x1 -+ PR_UNALIGN_SIGBUS = 0x2 -+ PSTOREFS_MAGIC = 0x6165676c -+ PTRACE_ATTACH = 0x10 -+ PTRACE_CONT = 0x7 -+ PTRACE_DETACH = 0x11 -+ PTRACE_EVENT_CLONE = 0x3 -+ PTRACE_EVENT_EXEC = 0x4 -+ PTRACE_EVENT_EXIT = 0x6 -+ PTRACE_EVENT_FORK = 0x1 -+ PTRACE_EVENT_SECCOMP = 0x7 -+ PTRACE_EVENT_STOP = 0x80 -+ PTRACE_EVENT_VFORK = 0x2 -+ PTRACE_EVENT_VFORK_DONE = 0x5 -+ PTRACE_GETEVENTMSG = 0x4201 -+ PTRACE_GETREGS = 0xc -+ PTRACE_GETREGSET = 0x4204 -+ PTRACE_GETSIGINFO = 0x4202 -+ PTRACE_GETSIGMASK = 0x420a -+ PTRACE_INTERRUPT = 0x4207 -+ PTRACE_KILL = 0x8 -+ PTRACE_LISTEN = 0x4208 -+ PTRACE_O_EXITKILL = 0x100000 -+ PTRACE_O_MASK = 0x3000ff -+ PTRACE_O_SUSPEND_SECCOMP = 0x200000 -+ PTRACE_O_TRACECLONE = 0x8 -+ PTRACE_O_TRACEEXEC = 0x10 -+ PTRACE_O_TRACEEXIT = 0x40 -+ PTRACE_O_TRACEFORK = 0x2 -+ PTRACE_O_TRACESECCOMP = 0x80 -+ PTRACE_O_TRACESYSGOOD = 0x1 -+ PTRACE_O_TRACEVFORK = 0x4 -+ PTRACE_O_TRACEVFORKDONE = 0x20 -+ PTRACE_PEEKDATA = 0x2 -+ PTRACE_PEEKSIGINFO = 0x4209 -+ PTRACE_PEEKSIGINFO_SHARED = 0x1 -+ PTRACE_PEEKTEXT = 0x1 -+ PTRACE_PEEKUSR = 0x3 -+ PTRACE_POKEDATA = 0x5 -+ PTRACE_POKETEXT = 0x4 -+ PTRACE_POKEUSR = 0x6 -+ PTRACE_SECCOMP_GET_FILTER = 0x420c -+ PTRACE_SECCOMP_GET_METADATA = 0x420d -+ PTRACE_SEIZE = 0x4206 -+ PTRACE_SETOPTIONS = 0x4200 -+ PTRACE_SETREGS = 0xd -+ PTRACE_SETREGSET = 0x4205 -+ PTRACE_SETSIGINFO = 0x4203 -+ PTRACE_SETSIGMASK = 0x420b -+ PTRACE_SINGLESTEP = 0x9 -+ PTRACE_SYSCALL = 0x18 -+ PTRACE_TRACEME = 0x0 -+ QNX4_SUPER_MAGIC = 0x2f -+ QNX6_SUPER_MAGIC = 0x68191122 -+ RAMFS_MAGIC = 0x858458f6 -+ RDTGROUP_SUPER_MAGIC = 0x7655821 -+ REISERFS_SUPER_MAGIC = 0x52654973 -+ RENAME_EXCHANGE = 0x2 -+ RENAME_NOREPLACE = 0x1 -+ RENAME_WHITEOUT = 0x4 -+ RLIMIT_AS = 0x9 -+ RLIMIT_CORE = 0x4 -+ RLIMIT_CPU = 0x0 -+ RLIMIT_DATA = 0x2 -+ RLIMIT_FSIZE = 0x1 -+ RLIMIT_LOCKS = 0xa -+ RLIMIT_MEMLOCK = 0x8 -+ RLIMIT_MSGQUEUE = 0xc -+ RLIMIT_NICE = 0xd -+ RLIMIT_NOFILE = 0x7 -+ RLIMIT_NPROC = 0x6 -+ RLIMIT_RSS = 0x5 -+ RLIMIT_RTPRIO = 0xe -+ RLIMIT_RTTIME = 0xf -+ RLIMIT_SIGPENDING = 0xb -+ RLIMIT_STACK = 0x3 -+ RLIM_INFINITY = 0xffffffffffffffff -+ RNDADDENTROPY = 0x40085203 -+ RNDADDTOENTCNT = 0x40045201 -+ RNDCLEARPOOL = 0x5206 -+ RNDGETENTCNT = 0x80045200 -+ RNDGETPOOL = 0x80085202 -+ RNDRESEEDCRNG = 0x5207 -+ RNDZAPENTCNT = 0x5204 -+ RTAX_ADVMSS = 0x8 -+ RTAX_CC_ALGO = 0x10 -+ RTAX_CWND = 0x7 -+ RTAX_FASTOPEN_NO_COOKIE = 0x11 -+ RTAX_FEATURES = 0xc -+ RTAX_FEATURE_ALLFRAG = 0x8 -+ RTAX_FEATURE_ECN = 0x1 -+ RTAX_FEATURE_MASK = 0xf -+ RTAX_FEATURE_SACK = 0x2 -+ RTAX_FEATURE_TIMESTAMP = 0x4 -+ RTAX_HOPLIMIT = 0xa -+ RTAX_INITCWND = 0xb -+ RTAX_INITRWND = 0xe -+ RTAX_LOCK = 0x1 -+ RTAX_MAX = 0x11 -+ RTAX_MTU = 0x2 -+ RTAX_QUICKACK = 0xf -+ RTAX_REORDERING = 0x9 -+ RTAX_RTO_MIN = 0xd -+ RTAX_RTT = 0x4 -+ RTAX_RTTVAR = 0x5 -+ RTAX_SSTHRESH = 0x6 -+ RTAX_UNSPEC = 0x0 -+ RTAX_WINDOW = 0x3 -+ RTA_ALIGNTO = 0x4 -+ RTA_MAX = 0x1d -+ RTCF_DIRECTSRC = 0x4000000 -+ RTCF_DOREDIRECT = 0x1000000 -+ RTCF_LOG = 0x2000000 -+ RTCF_MASQ = 0x400000 -+ RTCF_NAT = 0x800000 -+ RTCF_VALVE = 0x200000 -+ RTC_AF = 0x20 -+ RTC_AIE_OFF = 0x7002 -+ RTC_AIE_ON = 0x7001 -+ RTC_ALM_READ = 0x80247008 -+ RTC_ALM_SET = 0x40247007 -+ RTC_EPOCH_READ = 0x8008700d -+ RTC_EPOCH_SET = 0x4008700e -+ RTC_IRQF = 0x80 -+ RTC_IRQP_READ = 0x8008700b -+ RTC_IRQP_SET = 0x4008700c -+ RTC_MAX_FREQ = 0x2000 -+ RTC_PF = 0x40 -+ RTC_PIE_OFF = 0x7006 -+ RTC_PIE_ON = 0x7005 -+ RTC_PLL_GET = 0x80207011 -+ RTC_PLL_SET = 0x40207012 -+ RTC_RD_TIME = 0x80247009 -+ RTC_SET_TIME = 0x4024700a -+ RTC_UF = 0x10 -+ RTC_UIE_OFF = 0x7004 -+ RTC_UIE_ON = 0x7003 -+ RTC_VL_CLR = 0x7014 -+ RTC_VL_READ = 0x80047013 -+ RTC_WIE_OFF = 0x7010 -+ RTC_WIE_ON = 0x700f -+ RTC_WKALM_RD = 0x80287010 -+ RTC_WKALM_SET = 0x4028700f -+ RTF_ADDRCLASSMASK = 0xf8000000 -+ RTF_ADDRCONF = 0x40000 -+ RTF_ALLONLINK = 0x20000 -+ RTF_BROADCAST = 0x10000000 -+ RTF_CACHE = 0x1000000 -+ RTF_DEFAULT = 0x10000 -+ RTF_DYNAMIC = 0x10 -+ RTF_FLOW = 0x2000000 -+ RTF_GATEWAY = 0x2 -+ RTF_HOST = 0x4 -+ RTF_INTERFACE = 0x40000000 -+ RTF_IRTT = 0x100 -+ RTF_LINKRT = 0x100000 -+ RTF_LOCAL = 0x80000000 -+ RTF_MODIFIED = 0x20 -+ RTF_MSS = 0x40 -+ RTF_MTU = 0x40 -+ RTF_MULTICAST = 0x20000000 -+ RTF_NAT = 0x8000000 -+ RTF_NOFORWARD = 0x1000 -+ RTF_NONEXTHOP = 0x200000 -+ RTF_NOPMTUDISC = 0x4000 -+ RTF_POLICY = 0x4000000 -+ RTF_REINSTATE = 0x8 -+ RTF_REJECT = 0x200 -+ RTF_STATIC = 0x400 -+ RTF_THROW = 0x2000 -+ RTF_UP = 0x1 -+ RTF_WINDOW = 0x80 -+ RTF_XRESOLVE = 0x800 -+ RTM_BASE = 0x10 -+ RTM_DELACTION = 0x31 -+ RTM_DELADDR = 0x15 -+ RTM_DELADDRLABEL = 0x49 -+ RTM_DELCHAIN = 0x65 -+ RTM_DELLINK = 0x11 -+ RTM_DELMDB = 0x55 -+ RTM_DELNEIGH = 0x1d -+ RTM_DELNETCONF = 0x51 -+ RTM_DELNSID = 0x59 -+ RTM_DELQDISC = 0x25 -+ RTM_DELROUTE = 0x19 -+ RTM_DELRULE = 0x21 -+ RTM_DELTCLASS = 0x29 -+ RTM_DELTFILTER = 0x2d -+ RTM_F_CLONED = 0x200 -+ RTM_F_EQUALIZE = 0x400 -+ RTM_F_FIB_MATCH = 0x2000 -+ RTM_F_LOOKUP_TABLE = 0x1000 -+ RTM_F_NOTIFY = 0x100 -+ RTM_F_PREFIX = 0x800 -+ RTM_GETACTION = 0x32 -+ RTM_GETADDR = 0x16 -+ RTM_GETADDRLABEL = 0x4a -+ RTM_GETANYCAST = 0x3e -+ RTM_GETCHAIN = 0x66 -+ RTM_GETDCB = 0x4e -+ RTM_GETLINK = 0x12 -+ RTM_GETMDB = 0x56 -+ RTM_GETMULTICAST = 0x3a -+ RTM_GETNEIGH = 0x1e -+ RTM_GETNEIGHTBL = 0x42 -+ RTM_GETNETCONF = 0x52 -+ RTM_GETNSID = 0x5a -+ RTM_GETQDISC = 0x26 -+ RTM_GETROUTE = 0x1a -+ RTM_GETRULE = 0x22 -+ RTM_GETSTATS = 0x5e -+ RTM_GETTCLASS = 0x2a -+ RTM_GETTFILTER = 0x2e -+ RTM_MAX = 0x67 -+ RTM_NEWACTION = 0x30 -+ RTM_NEWADDR = 0x14 -+ RTM_NEWADDRLABEL = 0x48 -+ RTM_NEWCACHEREPORT = 0x60 -+ RTM_NEWCHAIN = 0x64 -+ RTM_NEWLINK = 0x10 -+ RTM_NEWMDB = 0x54 -+ RTM_NEWNDUSEROPT = 0x44 -+ RTM_NEWNEIGH = 0x1c -+ RTM_NEWNEIGHTBL = 0x40 -+ RTM_NEWNETCONF = 0x50 -+ RTM_NEWNSID = 0x58 -+ RTM_NEWPREFIX = 0x34 -+ RTM_NEWQDISC = 0x24 -+ RTM_NEWROUTE = 0x18 -+ RTM_NEWRULE = 0x20 -+ RTM_NEWSTATS = 0x5c -+ RTM_NEWTCLASS = 0x28 -+ RTM_NEWTFILTER = 0x2c -+ RTM_NR_FAMILIES = 0x16 -+ RTM_NR_MSGTYPES = 0x58 -+ RTM_SETDCB = 0x4f -+ RTM_SETLINK = 0x13 -+ RTM_SETNEIGHTBL = 0x43 -+ RTNH_ALIGNTO = 0x4 -+ RTNH_COMPARE_MASK = 0x19 -+ RTNH_F_DEAD = 0x1 -+ RTNH_F_LINKDOWN = 0x10 -+ RTNH_F_OFFLOAD = 0x8 -+ RTNH_F_ONLINK = 0x4 -+ RTNH_F_PERVASIVE = 0x2 -+ RTNH_F_UNRESOLVED = 0x20 -+ RTN_MAX = 0xb -+ RTPROT_BABEL = 0x2a -+ RTPROT_BGP = 0xba -+ RTPROT_BIRD = 0xc -+ RTPROT_BOOT = 0x3 -+ RTPROT_DHCP = 0x10 -+ RTPROT_DNROUTED = 0xd -+ RTPROT_EIGRP = 0xc0 -+ RTPROT_GATED = 0x8 -+ RTPROT_ISIS = 0xbb -+ RTPROT_KERNEL = 0x2 -+ RTPROT_MROUTED = 0x11 -+ RTPROT_MRT = 0xa -+ RTPROT_NTK = 0xf -+ RTPROT_OSPF = 0xbc -+ RTPROT_RA = 0x9 -+ RTPROT_REDIRECT = 0x1 -+ RTPROT_RIP = 0xbd -+ RTPROT_STATIC = 0x4 -+ RTPROT_UNSPEC = 0x0 -+ RTPROT_XORP = 0xe -+ RTPROT_ZEBRA = 0xb -+ RT_CLASS_DEFAULT = 0xfd -+ RT_CLASS_LOCAL = 0xff -+ RT_CLASS_MAIN = 0xfe -+ RT_CLASS_MAX = 0xff -+ RT_CLASS_UNSPEC = 0x0 -+ RUSAGE_CHILDREN = -0x1 -+ RUSAGE_SELF = 0x0 -+ RUSAGE_THREAD = 0x1 -+ SCM_CREDENTIALS = 0x2 -+ SCM_RIGHTS = 0x1 -+ SCM_TIMESTAMP = 0x1d -+ SCM_TIMESTAMPING = 0x25 -+ SCM_TIMESTAMPING_OPT_STATS = 0x36 -+ SCM_TIMESTAMPING_PKTINFO = 0x3a -+ SCM_TIMESTAMPNS = 0x23 -+ SCM_TXTIME = 0x3d -+ SCM_WIFI_STATUS = 0x29 -+ SC_LOG_FLUSH = 0x100000 -+ SECCOMP_MODE_DISABLED = 0x0 -+ SECCOMP_MODE_FILTER = 0x2 -+ SECCOMP_MODE_STRICT = 0x1 -+ SECURITYFS_MAGIC = 0x73636673 -+ SELINUX_MAGIC = 0xf97cff8c -+ SFD_CLOEXEC = 0x80000 -+ SFD_NONBLOCK = 0x800 -+ SHUT_RD = 0x0 -+ SHUT_RDWR = 0x2 -+ SHUT_WR = 0x1 -+ SIOCADDDLCI = 0x8980 -+ SIOCADDMULTI = 0x8931 -+ SIOCADDRT = 0x890b -+ SIOCATMARK = 0x8905 -+ SIOCBONDCHANGEACTIVE = 0x8995 -+ SIOCBONDENSLAVE = 0x8990 -+ SIOCBONDINFOQUERY = 0x8994 -+ SIOCBONDRELEASE = 0x8991 -+ SIOCBONDSETHWADDR = 0x8992 -+ SIOCBONDSLAVEINFOQUERY = 0x8993 -+ SIOCBRADDBR = 0x89a0 -+ SIOCBRADDIF = 0x89a2 -+ SIOCBRDELBR = 0x89a1 -+ SIOCBRDELIF = 0x89a3 -+ SIOCDARP = 0x8953 -+ SIOCDELDLCI = 0x8981 -+ SIOCDELMULTI = 0x8932 -+ SIOCDELRT = 0x890c -+ SIOCDEVPRIVATE = 0x89f0 -+ SIOCDIFADDR = 0x8936 -+ SIOCDRARP = 0x8960 -+ SIOCETHTOOL = 0x8946 -+ SIOCGARP = 0x8954 -+ SIOCGHWTSTAMP = 0x89b1 -+ SIOCGIFADDR = 0x8915 -+ SIOCGIFBR = 0x8940 -+ SIOCGIFBRDADDR = 0x8919 -+ SIOCGIFCONF = 0x8912 -+ SIOCGIFCOUNT = 0x8938 -+ SIOCGIFDSTADDR = 0x8917 -+ SIOCGIFENCAP = 0x8925 -+ SIOCGIFFLAGS = 0x8913 -+ SIOCGIFHWADDR = 0x8927 -+ SIOCGIFINDEX = 0x8933 -+ SIOCGIFMAP = 0x8970 -+ SIOCGIFMEM = 0x891f -+ SIOCGIFMETRIC = 0x891d -+ SIOCGIFMTU = 0x8921 -+ SIOCGIFNAME = 0x8910 -+ SIOCGIFNETMASK = 0x891b -+ SIOCGIFPFLAGS = 0x8935 -+ SIOCGIFSLAVE = 0x8929 -+ SIOCGIFTXQLEN = 0x8942 -+ SIOCGIFVLAN = 0x8982 -+ SIOCGMIIPHY = 0x8947 -+ SIOCGMIIREG = 0x8948 -+ SIOCGPGRP = 0x8904 -+ SIOCGPPPCSTATS = 0x89f2 -+ SIOCGPPPSTATS = 0x89f0 -+ SIOCGPPPVER = 0x89f1 -+ SIOCGRARP = 0x8961 -+ SIOCGSKNS = 0x894c -+ SIOCGSTAMP = 0x8906 -+ SIOCGSTAMPNS = 0x8907 -+ SIOCINQ = 0x541b -+ SIOCOUTQ = 0x5411 -+ SIOCOUTQNSD = 0x894b -+ SIOCPROTOPRIVATE = 0x89e0 -+ SIOCRTMSG = 0x890d -+ SIOCSARP = 0x8955 -+ SIOCSHWTSTAMP = 0x89b0 -+ SIOCSIFADDR = 0x8916 -+ SIOCSIFBR = 0x8941 -+ SIOCSIFBRDADDR = 0x891a -+ SIOCSIFDSTADDR = 0x8918 -+ SIOCSIFENCAP = 0x8926 -+ SIOCSIFFLAGS = 0x8914 -+ SIOCSIFHWADDR = 0x8924 -+ SIOCSIFHWBROADCAST = 0x8937 -+ SIOCSIFLINK = 0x8911 -+ SIOCSIFMAP = 0x8971 -+ SIOCSIFMEM = 0x8920 -+ SIOCSIFMETRIC = 0x891e -+ SIOCSIFMTU = 0x8922 -+ SIOCSIFNAME = 0x8923 -+ SIOCSIFNETMASK = 0x891c -+ SIOCSIFPFLAGS = 0x8934 -+ SIOCSIFSLAVE = 0x8930 -+ SIOCSIFTXQLEN = 0x8943 -+ SIOCSIFVLAN = 0x8983 -+ SIOCSMIIREG = 0x8949 -+ SIOCSPGRP = 0x8902 -+ SIOCSRARP = 0x8962 -+ SIOCWANDEV = 0x894a -+ SMACK_MAGIC = 0x43415d53 -+ SMART_AUTOSAVE = 0xd2 -+ SMART_AUTO_OFFLINE = 0xdb -+ SMART_DISABLE = 0xd9 -+ SMART_ENABLE = 0xd8 -+ SMART_HCYL_PASS = 0xc2 -+ SMART_IMMEDIATE_OFFLINE = 0xd4 -+ SMART_LCYL_PASS = 0x4f -+ SMART_READ_LOG_SECTOR = 0xd5 -+ SMART_READ_THRESHOLDS = 0xd1 -+ SMART_READ_VALUES = 0xd0 -+ SMART_SAVE = 0xd3 -+ SMART_STATUS = 0xda -+ SMART_WRITE_LOG_SECTOR = 0xd6 -+ SMART_WRITE_THRESHOLDS = 0xd7 -+ SMB_SUPER_MAGIC = 0x517b -+ SOCKFS_MAGIC = 0x534f434b -+ SOCK_CLOEXEC = 0x80000 -+ SOCK_DCCP = 0x6 -+ SOCK_DGRAM = 0x2 -+ SOCK_IOC_TYPE = 0x89 -+ SOCK_NONBLOCK = 0x800 -+ SOCK_PACKET = 0xa -+ SOCK_RAW = 0x3 -+ SOCK_RDM = 0x4 -+ SOCK_SEQPACKET = 0x5 -+ SOCK_STREAM = 0x1 -+ SOL_AAL = 0x109 -+ SOL_ALG = 0x117 -+ SOL_ATM = 0x108 -+ SOL_CAIF = 0x116 -+ SOL_CAN_BASE = 0x64 -+ SOL_DCCP = 0x10d -+ SOL_DECNET = 0x105 -+ SOL_ICMPV6 = 0x3a -+ SOL_IP = 0x0 -+ SOL_IPV6 = 0x29 -+ SOL_IRDA = 0x10a -+ SOL_IUCV = 0x115 -+ SOL_KCM = 0x119 -+ SOL_LLC = 0x10c -+ SOL_NETBEUI = 0x10b -+ SOL_NETLINK = 0x10e -+ SOL_NFC = 0x118 -+ SOL_PACKET = 0x107 -+ SOL_PNPIPE = 0x113 -+ SOL_PPPOL2TP = 0x111 -+ SOL_RAW = 0xff -+ SOL_RDS = 0x114 -+ SOL_RXRPC = 0x110 -+ SOL_SOCKET = 0x1 -+ SOL_TCP = 0x6 -+ SOL_TIPC = 0x10f -+ SOL_TLS = 0x11a -+ SOL_X25 = 0x106 -+ SOL_XDP = 0x11b -+ SOMAXCONN = 0x80 -+ SO_ACCEPTCONN = 0x1e -+ SO_ATTACH_BPF = 0x32 -+ SO_ATTACH_FILTER = 0x1a -+ SO_ATTACH_REUSEPORT_CBPF = 0x33 -+ SO_ATTACH_REUSEPORT_EBPF = 0x34 -+ SO_BINDTODEVICE = 0x19 -+ SO_BPF_EXTENSIONS = 0x30 -+ SO_BROADCAST = 0x6 -+ SO_BSDCOMPAT = 0xe -+ SO_BUSY_POLL = 0x2e -+ SO_CNX_ADVICE = 0x35 -+ SO_COOKIE = 0x39 -+ SO_DEBUG = 0x1 -+ SO_DETACH_BPF = 0x1b -+ SO_DETACH_FILTER = 0x1b -+ SO_DOMAIN = 0x27 -+ SO_DONTROUTE = 0x5 -+ SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 -+ SO_EE_CODE_TXTIME_MISSED = 0x2 -+ SO_EE_CODE_ZEROCOPY_COPIED = 0x1 -+ SO_EE_ORIGIN_ICMP = 0x2 -+ SO_EE_ORIGIN_ICMP6 = 0x3 -+ SO_EE_ORIGIN_LOCAL = 0x1 -+ SO_EE_ORIGIN_NONE = 0x0 -+ SO_EE_ORIGIN_TIMESTAMPING = 0x4 -+ SO_EE_ORIGIN_TXSTATUS = 0x4 -+ SO_EE_ORIGIN_TXTIME = 0x6 -+ SO_EE_ORIGIN_ZEROCOPY = 0x5 -+ SO_ERROR = 0x4 -+ SO_GET_FILTER = 0x1a -+ SO_INCOMING_CPU = 0x31 -+ SO_INCOMING_NAPI_ID = 0x38 -+ SO_KEEPALIVE = 0x9 -+ SO_LINGER = 0xd -+ SO_LOCK_FILTER = 0x2c -+ SO_MARK = 0x24 -+ SO_MAX_PACING_RATE = 0x2f -+ SO_MEMINFO = 0x37 -+ SO_NOFCS = 0x2b -+ SO_NO_CHECK = 0xb -+ SO_OOBINLINE = 0xa -+ SO_PASSCRED = 0x10 -+ SO_PASSSEC = 0x22 -+ SO_PEEK_OFF = 0x2a -+ SO_PEERCRED = 0x11 -+ SO_PEERGROUPS = 0x3b -+ SO_PEERNAME = 0x1c -+ SO_PEERSEC = 0x1f -+ SO_PRIORITY = 0xc -+ SO_PROTOCOL = 0x26 -+ SO_RCVBUF = 0x8 -+ SO_RCVBUFFORCE = 0x21 -+ SO_RCVLOWAT = 0x12 -+ SO_RCVTIMEO = 0x14 -+ SO_REUSEADDR = 0x2 -+ SO_REUSEPORT = 0xf -+ SO_RXQ_OVFL = 0x28 -+ SO_SECURITY_AUTHENTICATION = 0x16 -+ SO_SECURITY_ENCRYPTION_NETWORK = 0x18 -+ SO_SECURITY_ENCRYPTION_TRANSPORT = 0x17 -+ SO_SELECT_ERR_QUEUE = 0x2d -+ SO_SNDBUF = 0x7 -+ SO_SNDBUFFORCE = 0x20 -+ SO_SNDLOWAT = 0x13 -+ SO_SNDTIMEO = 0x15 -+ SO_TIMESTAMP = 0x1d -+ SO_TIMESTAMPING = 0x25 -+ SO_TIMESTAMPNS = 0x23 -+ SO_TXTIME = 0x3d -+ SO_TYPE = 0x3 -+ SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2 -+ SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1 -+ SO_VM_SOCKETS_BUFFER_SIZE = 0x0 -+ SO_VM_SOCKETS_CONNECT_TIMEOUT = 0x6 -+ SO_VM_SOCKETS_NONBLOCK_TXRX = 0x7 -+ SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 -+ SO_VM_SOCKETS_TRUSTED = 0x5 -+ SO_WIFI_STATUS = 0x29 -+ SO_ZEROCOPY = 0x3c -+ SPLICE_F_GIFT = 0x8 -+ SPLICE_F_MORE = 0x4 -+ SPLICE_F_MOVE = 0x1 -+ SPLICE_F_NONBLOCK = 0x2 -+ SQUASHFS_MAGIC = 0x73717368 -+ STACK_END_MAGIC = 0x57ac6e9d -+ STATX_ALL = 0xfff -+ STATX_ATIME = 0x20 -+ STATX_ATTR_APPEND = 0x20 -+ STATX_ATTR_AUTOMOUNT = 0x1000 -+ STATX_ATTR_COMPRESSED = 0x4 -+ STATX_ATTR_ENCRYPTED = 0x800 -+ STATX_ATTR_IMMUTABLE = 0x10 -+ STATX_ATTR_NODUMP = 0x40 -+ STATX_BASIC_STATS = 0x7ff -+ STATX_BLOCKS = 0x400 -+ STATX_BTIME = 0x800 -+ STATX_CTIME = 0x80 -+ STATX_GID = 0x10 -+ STATX_INO = 0x100 -+ STATX_MODE = 0x2 -+ STATX_MTIME = 0x40 -+ STATX_NLINK = 0x4 -+ STATX_SIZE = 0x200 -+ STATX_TYPE = 0x1 -+ STATX_UID = 0x8 -+ STATX__RESERVED = 0x80000000 -+ SYNC_FILE_RANGE_WAIT_AFTER = 0x4 -+ SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 -+ SYNC_FILE_RANGE_WRITE = 0x2 -+ SYSFS_MAGIC = 0x62656572 -+ S_BLKSIZE = 0x200 -+ S_IEXEC = 0x40 -+ S_IFBLK = 0x6000 -+ S_IFCHR = 0x2000 -+ S_IFDIR = 0x4000 -+ S_IFIFO = 0x1000 -+ S_IFLNK = 0xa000 -+ S_IFMT = 0xf000 -+ S_IFREG = 0x8000 -+ S_IFSOCK = 0xc000 -+ S_IREAD = 0x100 -+ S_IRGRP = 0x20 -+ S_IROTH = 0x4 -+ S_IRUSR = 0x100 -+ S_IRWXG = 0x38 -+ S_IRWXO = 0x7 -+ S_IRWXU = 0x1c0 -+ S_ISGID = 0x400 -+ S_ISUID = 0x800 -+ S_ISVTX = 0x200 -+ S_IWGRP = 0x10 -+ S_IWOTH = 0x2 -+ S_IWRITE = 0x80 -+ S_IWUSR = 0x80 -+ S_IXGRP = 0x8 -+ S_IXOTH = 0x1 -+ S_IXUSR = 0x40 -+ TAB0 = 0x0 -+ TAB1 = 0x800 -+ TAB2 = 0x1000 -+ TAB3 = 0x1800 -+ TABDLY = 0x1800 -+ TASKSTATS_CMD_ATTR_MAX = 0x4 -+ TASKSTATS_CMD_MAX = 0x2 -+ TASKSTATS_GENL_NAME = "TASKSTATS" -+ TASKSTATS_GENL_VERSION = 0x1 -+ TASKSTATS_TYPE_MAX = 0x6 -+ TASKSTATS_VERSION = 0x9 -+ TCFLSH = 0x540b -+ TCGETA = 0x5405 -+ TCGETS = 0x5401 -+ TCGETS2 = 0x802c542a -+ TCGETX = 0x5432 -+ TCIFLUSH = 0x0 -+ TCIOFF = 0x2 -+ TCIOFLUSH = 0x2 -+ TCION = 0x3 -+ TCOFLUSH = 0x1 -+ TCOOFF = 0x0 -+ TCOON = 0x1 -+ TCP_CC_INFO = 0x1a -+ TCP_CM_INQ = 0x24 -+ TCP_CONGESTION = 0xd -+ TCP_COOKIE_IN_ALWAYS = 0x1 -+ TCP_COOKIE_MAX = 0x10 -+ TCP_COOKIE_MIN = 0x8 -+ TCP_COOKIE_OUT_NEVER = 0x2 -+ TCP_COOKIE_PAIR_SIZE = 0x20 -+ TCP_COOKIE_TRANSACTIONS = 0xf -+ TCP_CORK = 0x3 -+ TCP_DEFER_ACCEPT = 0x9 -+ TCP_FASTOPEN = 0x17 -+ TCP_FASTOPEN_CONNECT = 0x1e -+ TCP_FASTOPEN_KEY = 0x21 -+ TCP_FASTOPEN_NO_COOKIE = 0x22 -+ TCP_INFO = 0xb -+ TCP_INQ = 0x24 -+ TCP_KEEPCNT = 0x6 -+ TCP_KEEPIDLE = 0x4 -+ TCP_KEEPINTVL = 0x5 -+ TCP_LINGER2 = 0x8 -+ TCP_MAXSEG = 0x2 -+ TCP_MAXWIN = 0xffff -+ TCP_MAX_WINSHIFT = 0xe -+ TCP_MD5SIG = 0xe -+ TCP_MD5SIG_EXT = 0x20 -+ TCP_MD5SIG_FLAG_PREFIX = 0x1 -+ TCP_MD5SIG_MAXKEYLEN = 0x50 -+ TCP_MSS = 0x200 -+ TCP_MSS_DEFAULT = 0x218 -+ TCP_MSS_DESIRED = 0x4c4 -+ TCP_NODELAY = 0x1 -+ TCP_NOTSENT_LOWAT = 0x19 -+ TCP_QUEUE_SEQ = 0x15 -+ TCP_QUICKACK = 0xc -+ TCP_REPAIR = 0x13 -+ TCP_REPAIR_OFF = 0x0 -+ TCP_REPAIR_OFF_NO_WP = -0x1 -+ TCP_REPAIR_ON = 0x1 -+ TCP_REPAIR_OPTIONS = 0x16 -+ TCP_REPAIR_QUEUE = 0x14 -+ TCP_REPAIR_WINDOW = 0x1d -+ TCP_SAVED_SYN = 0x1c -+ TCP_SAVE_SYN = 0x1b -+ TCP_SYNCNT = 0x7 -+ TCP_S_DATA_IN = 0x4 -+ TCP_S_DATA_OUT = 0x8 -+ TCP_THIN_DUPACK = 0x11 -+ TCP_THIN_LINEAR_TIMEOUTS = 0x10 -+ TCP_TIMESTAMP = 0x18 -+ TCP_ULP = 0x1f -+ TCP_USER_TIMEOUT = 0x12 -+ TCP_WINDOW_CLAMP = 0xa -+ TCP_ZEROCOPY_RECEIVE = 0x23 -+ TCSAFLUSH = 0x2 -+ TCSBRK = 0x5409 -+ TCSBRKP = 0x5425 -+ TCSETA = 0x5406 -+ TCSETAF = 0x5408 -+ TCSETAW = 0x5407 -+ TCSETS = 0x5402 -+ TCSETS2 = 0x402c542b -+ TCSETSF = 0x5404 -+ TCSETSF2 = 0x402c542d -+ TCSETSW = 0x5403 -+ TCSETSW2 = 0x402c542c -+ TCSETX = 0x5433 -+ TCSETXF = 0x5434 -+ TCSETXW = 0x5435 -+ TCXONC = 0x540a -+ TIMER_ABSTIME = 0x1 -+ TIOCCBRK = 0x5428 -+ TIOCCONS = 0x541d -+ TIOCEXCL = 0x540c -+ TIOCGDEV = 0x80045432 -+ TIOCGETD = 0x5424 -+ TIOCGEXCL = 0x80045440 -+ TIOCGICOUNT = 0x545d -+ TIOCGISO7816 = 0x80285442 -+ TIOCGLCKTRMIOS = 0x5456 -+ TIOCGPGRP = 0x540f -+ TIOCGPKT = 0x80045438 -+ TIOCGPTLCK = 0x80045439 -+ TIOCGPTN = 0x80045430 -+ TIOCGPTPEER = 0x5441 -+ TIOCGRS485 = 0x542e -+ TIOCGSERIAL = 0x541e -+ TIOCGSID = 0x5429 -+ TIOCGSOFTCAR = 0x5419 -+ TIOCGWINSZ = 0x5413 -+ TIOCINQ = 0x541b -+ TIOCLINUX = 0x541c -+ TIOCMBIC = 0x5417 -+ TIOCMBIS = 0x5416 -+ TIOCMGET = 0x5415 -+ TIOCMIWAIT = 0x545c -+ TIOCMSET = 0x5418 -+ TIOCM_CAR = 0x40 -+ TIOCM_CD = 0x40 -+ TIOCM_CTS = 0x20 -+ TIOCM_DSR = 0x100 -+ TIOCM_DTR = 0x2 -+ TIOCM_LE = 0x1 -+ TIOCM_RI = 0x80 -+ TIOCM_RNG = 0x80 -+ TIOCM_RTS = 0x4 -+ TIOCM_SR = 0x10 -+ TIOCM_ST = 0x8 -+ TIOCNOTTY = 0x5422 -+ TIOCNXCL = 0x540d -+ TIOCOUTQ = 0x5411 -+ TIOCPKT = 0x5420 -+ TIOCPKT_DATA = 0x0 -+ TIOCPKT_DOSTOP = 0x20 -+ TIOCPKT_FLUSHREAD = 0x1 -+ TIOCPKT_FLUSHWRITE = 0x2 -+ TIOCPKT_IOCTL = 0x40 -+ TIOCPKT_NOSTOP = 0x10 -+ TIOCPKT_START = 0x8 -+ TIOCPKT_STOP = 0x4 -+ TIOCSBRK = 0x5427 -+ TIOCSCTTY = 0x540e -+ TIOCSERCONFIG = 0x5453 -+ TIOCSERGETLSR = 0x5459 -+ TIOCSERGETMULTI = 0x545a -+ TIOCSERGSTRUCT = 0x5458 -+ TIOCSERGWILD = 0x5454 -+ TIOCSERSETMULTI = 0x545b -+ TIOCSERSWILD = 0x5455 -+ TIOCSER_TEMT = 0x1 -+ TIOCSETD = 0x5423 -+ TIOCSIG = 0x40045436 -+ TIOCSISO7816 = 0xc0285443 -+ TIOCSLCKTRMIOS = 0x5457 -+ TIOCSPGRP = 0x5410 -+ TIOCSPTLCK = 0x40045431 -+ TIOCSRS485 = 0x542f -+ TIOCSSERIAL = 0x541f -+ TIOCSSOFTCAR = 0x541a -+ TIOCSTI = 0x5412 -+ TIOCSWINSZ = 0x5414 -+ TIOCVHANGUP = 0x5437 -+ TMPFS_MAGIC = 0x1021994 -+ TOSTOP = 0x100 -+ TPACKET_ALIGNMENT = 0x10 -+ TPACKET_HDRLEN = 0x34 -+ TP_STATUS_AVAILABLE = 0x0 -+ TP_STATUS_BLK_TMO = 0x20 -+ TP_STATUS_COPY = 0x2 -+ TP_STATUS_CSUMNOTREADY = 0x8 -+ TP_STATUS_CSUM_VALID = 0x80 -+ TP_STATUS_KERNEL = 0x0 -+ TP_STATUS_LOSING = 0x4 -+ TP_STATUS_SENDING = 0x2 -+ TP_STATUS_SEND_REQUEST = 0x1 -+ TP_STATUS_TS_RAW_HARDWARE = -0x80000000 -+ TP_STATUS_TS_SOFTWARE = 0x20000000 -+ TP_STATUS_TS_SYS_HARDWARE = 0x40000000 -+ TP_STATUS_USER = 0x1 -+ TP_STATUS_VLAN_TPID_VALID = 0x40 -+ TP_STATUS_VLAN_VALID = 0x10 -+ TP_STATUS_WRONG_FORMAT = 0x4 -+ TRACEFS_MAGIC = 0x74726163 -+ TS_COMM_LEN = 0x20 -+ TUNATTACHFILTER = 0x401054d5 -+ TUNDETACHFILTER = 0x401054d6 -+ TUNGETFEATURES = 0x800454cf -+ TUNGETFILTER = 0x801054db -+ TUNGETIFF = 0x800454d2 -+ TUNGETSNDBUF = 0x800454d3 -+ TUNGETVNETBE = 0x800454df -+ TUNGETVNETHDRSZ = 0x800454d7 -+ TUNGETVNETLE = 0x800454dd -+ TUNSETDEBUG = 0x400454c9 -+ TUNSETFILTEREBPF = 0x800454e1 -+ TUNSETGROUP = 0x400454ce -+ TUNSETIFF = 0x400454ca -+ TUNSETIFINDEX = 0x400454da -+ TUNSETLINK = 0x400454cd -+ TUNSETNOCSUM = 0x400454c8 -+ TUNSETOFFLOAD = 0x400454d0 -+ TUNSETOWNER = 0x400454cc -+ TUNSETPERSIST = 0x400454cb -+ TUNSETQUEUE = 0x400454d9 -+ TUNSETSNDBUF = 0x400454d4 -+ TUNSETSTEERINGEBPF = 0x800454e0 -+ TUNSETTXFILTER = 0x400454d1 -+ TUNSETVNETBE = 0x400454de -+ TUNSETVNETHDRSZ = 0x400454d8 -+ TUNSETVNETLE = 0x400454dc -+ UBI_IOCATT = 0x40186f40 -+ UBI_IOCDET = 0x40046f41 -+ UBI_IOCEBCH = 0x40044f02 -+ UBI_IOCEBER = 0x40044f01 -+ UBI_IOCEBISMAP = 0x80044f05 -+ UBI_IOCEBMAP = 0x40084f03 -+ UBI_IOCEBUNMAP = 0x40044f04 -+ UBI_IOCMKVOL = 0x40986f00 -+ UBI_IOCRMVOL = 0x40046f01 -+ UBI_IOCRNVOL = 0x51106f03 -+ UBI_IOCRSVOL = 0x400c6f02 -+ UBI_IOCSETVOLPROP = 0x40104f06 -+ UBI_IOCVOLCRBLK = 0x40804f07 -+ UBI_IOCVOLRMBLK = 0x4f08 -+ UBI_IOCVOLUP = 0x40084f00 -+ UDF_SUPER_MAGIC = 0x15013346 -+ UMOUNT_NOFOLLOW = 0x8 -+ USBDEVICE_SUPER_MAGIC = 0x9fa2 -+ UTIME_NOW = 0x3fffffff -+ UTIME_OMIT = 0x3ffffffe -+ V9FS_MAGIC = 0x1021997 -+ VDISCARD = 0xd -+ VEOF = 0x4 -+ VEOL = 0xb -+ VEOL2 = 0x10 -+ VERASE = 0x2 -+ VINTR = 0x0 -+ VKILL = 0x3 -+ VLNEXT = 0xf -+ VMADDR_CID_ANY = 0xffffffff -+ VMADDR_CID_HOST = 0x2 -+ VMADDR_CID_HYPERVISOR = 0x0 -+ VMADDR_CID_RESERVED = 0x1 -+ VMADDR_PORT_ANY = 0xffffffff -+ VMIN = 0x6 -+ VM_SOCKETS_INVALID_VERSION = 0xffffffff -+ VQUIT = 0x1 -+ VREPRINT = 0xc -+ VSTART = 0x8 -+ VSTOP = 0x9 -+ VSUSP = 0xa -+ VSWTC = 0x7 -+ VT0 = 0x0 -+ VT1 = 0x4000 -+ VTDLY = 0x4000 -+ VTIME = 0x5 -+ VWERASE = 0xe -+ WALL = 0x40000000 -+ WCLONE = 0x80000000 -+ WCONTINUED = 0x8 -+ WDIOC_GETBOOTSTATUS = 0x80045702 -+ WDIOC_GETPRETIMEOUT = 0x80045709 -+ WDIOC_GETSTATUS = 0x80045701 -+ WDIOC_GETSUPPORT = 0x80285700 -+ WDIOC_GETTEMP = 0x80045703 -+ WDIOC_GETTIMELEFT = 0x8004570a -+ WDIOC_GETTIMEOUT = 0x80045707 -+ WDIOC_KEEPALIVE = 0x80045705 -+ WDIOC_SETOPTIONS = 0x80045704 -+ WDIOC_SETPRETIMEOUT = 0xc0045708 -+ WDIOC_SETTIMEOUT = 0xc0045706 -+ WEXITED = 0x4 -+ WIN_ACKMEDIACHANGE = 0xdb -+ WIN_CHECKPOWERMODE1 = 0xe5 -+ WIN_CHECKPOWERMODE2 = 0x98 -+ WIN_DEVICE_RESET = 0x8 -+ WIN_DIAGNOSE = 0x90 -+ WIN_DOORLOCK = 0xde -+ WIN_DOORUNLOCK = 0xdf -+ WIN_DOWNLOAD_MICROCODE = 0x92 -+ WIN_FLUSH_CACHE = 0xe7 -+ WIN_FLUSH_CACHE_EXT = 0xea -+ WIN_FORMAT = 0x50 -+ WIN_GETMEDIASTATUS = 0xda -+ WIN_IDENTIFY = 0xec -+ WIN_IDENTIFY_DMA = 0xee -+ WIN_IDLEIMMEDIATE = 0xe1 -+ WIN_INIT = 0x60 -+ WIN_MEDIAEJECT = 0xed -+ WIN_MULTREAD = 0xc4 -+ WIN_MULTREAD_EXT = 0x29 -+ WIN_MULTWRITE = 0xc5 -+ WIN_MULTWRITE_EXT = 0x39 -+ WIN_NOP = 0x0 -+ WIN_PACKETCMD = 0xa0 -+ WIN_PIDENTIFY = 0xa1 -+ WIN_POSTBOOT = 0xdc -+ WIN_PREBOOT = 0xdd -+ WIN_QUEUED_SERVICE = 0xa2 -+ WIN_READ = 0x20 -+ WIN_READDMA = 0xc8 -+ WIN_READDMA_EXT = 0x25 -+ WIN_READDMA_ONCE = 0xc9 -+ WIN_READDMA_QUEUED = 0xc7 -+ WIN_READDMA_QUEUED_EXT = 0x26 -+ WIN_READ_BUFFER = 0xe4 -+ WIN_READ_EXT = 0x24 -+ WIN_READ_LONG = 0x22 -+ WIN_READ_LONG_ONCE = 0x23 -+ WIN_READ_NATIVE_MAX = 0xf8 -+ WIN_READ_NATIVE_MAX_EXT = 0x27 -+ WIN_READ_ONCE = 0x21 -+ WIN_RECAL = 0x10 -+ WIN_RESTORE = 0x10 -+ WIN_SECURITY_DISABLE = 0xf6 -+ WIN_SECURITY_ERASE_PREPARE = 0xf3 -+ WIN_SECURITY_ERASE_UNIT = 0xf4 -+ WIN_SECURITY_FREEZE_LOCK = 0xf5 -+ WIN_SECURITY_SET_PASS = 0xf1 -+ WIN_SECURITY_UNLOCK = 0xf2 -+ WIN_SEEK = 0x70 -+ WIN_SETFEATURES = 0xef -+ WIN_SETIDLE1 = 0xe3 -+ WIN_SETIDLE2 = 0x97 -+ WIN_SETMULT = 0xc6 -+ WIN_SET_MAX = 0xf9 -+ WIN_SET_MAX_EXT = 0x37 -+ WIN_SLEEPNOW1 = 0xe6 -+ WIN_SLEEPNOW2 = 0x99 -+ WIN_SMART = 0xb0 -+ WIN_SPECIFY = 0x91 -+ WIN_SRST = 0x8 -+ WIN_STANDBY = 0xe2 -+ WIN_STANDBY2 = 0x96 -+ WIN_STANDBYNOW1 = 0xe0 -+ WIN_STANDBYNOW2 = 0x94 -+ WIN_VERIFY = 0x40 -+ WIN_VERIFY_EXT = 0x42 -+ WIN_VERIFY_ONCE = 0x41 -+ WIN_WRITE = 0x30 -+ WIN_WRITEDMA = 0xca -+ WIN_WRITEDMA_EXT = 0x35 -+ WIN_WRITEDMA_ONCE = 0xcb -+ WIN_WRITEDMA_QUEUED = 0xcc -+ WIN_WRITEDMA_QUEUED_EXT = 0x36 -+ WIN_WRITE_BUFFER = 0xe8 -+ WIN_WRITE_EXT = 0x34 -+ WIN_WRITE_LONG = 0x32 -+ WIN_WRITE_LONG_ONCE = 0x33 -+ WIN_WRITE_ONCE = 0x31 -+ WIN_WRITE_SAME = 0xe9 -+ WIN_WRITE_VERIFY = 0x3c -+ WNOHANG = 0x1 -+ WNOTHREAD = 0x20000000 -+ WNOWAIT = 0x1000000 -+ WORDSIZE = 0x40 -+ WSTOPPED = 0x2 -+ WUNTRACED = 0x2 -+ XATTR_CREATE = 0x1 -+ XATTR_REPLACE = 0x2 -+ XCASE = 0x4 -+ XDP_COPY = 0x2 -+ XDP_FLAGS_DRV_MODE = 0x4 -+ XDP_FLAGS_HW_MODE = 0x8 -+ XDP_FLAGS_MASK = 0xf -+ XDP_FLAGS_MODES = 0xe -+ XDP_FLAGS_SKB_MODE = 0x2 -+ XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1 -+ XDP_MMAP_OFFSETS = 0x1 -+ XDP_PGOFF_RX_RING = 0x0 -+ XDP_PGOFF_TX_RING = 0x80000000 -+ XDP_RX_RING = 0x2 -+ XDP_SHARED_UMEM = 0x1 -+ XDP_STATISTICS = 0x7 -+ XDP_TX_RING = 0x3 -+ XDP_UMEM_COMPLETION_RING = 0x6 -+ XDP_UMEM_FILL_RING = 0x5 -+ XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000 -+ XDP_UMEM_PGOFF_FILL_RING = 0x100000000 -+ XDP_UMEM_REG = 0x4 -+ XDP_ZEROCOPY = 0x4 -+ XENFS_SUPER_MAGIC = 0xabba1974 -+ XFS_SUPER_MAGIC = 0x58465342 -+ XTABS = 0x1800 -+ ZSMALLOC_MAGIC = 0x58295829 -+) -+ -+// Errors -+const ( -+ E2BIG = syscall.Errno(0x7) -+ EACCES = syscall.Errno(0xd) -+ EADDRINUSE = syscall.Errno(0x62) -+ EADDRNOTAVAIL = syscall.Errno(0x63) -+ EADV = syscall.Errno(0x44) -+ EAFNOSUPPORT = syscall.Errno(0x61) -+ EAGAIN = syscall.Errno(0xb) -+ EALREADY = syscall.Errno(0x72) -+ EBADE = syscall.Errno(0x34) -+ EBADF = syscall.Errno(0x9) -+ EBADFD = syscall.Errno(0x4d) -+ EBADMSG = syscall.Errno(0x4a) -+ EBADR = syscall.Errno(0x35) -+ EBADRQC = syscall.Errno(0x38) -+ EBADSLT = syscall.Errno(0x39) -+ EBFONT = syscall.Errno(0x3b) -+ EBUSY = syscall.Errno(0x10) -+ ECANCELED = syscall.Errno(0x7d) -+ ECHILD = syscall.Errno(0xa) -+ ECHRNG = syscall.Errno(0x2c) -+ ECOMM = syscall.Errno(0x46) -+ ECONNABORTED = syscall.Errno(0x67) -+ ECONNREFUSED = syscall.Errno(0x6f) -+ ECONNRESET = syscall.Errno(0x68) -+ EDEADLK = syscall.Errno(0x23) -+ EDEADLOCK = syscall.Errno(0x23) -+ EDESTADDRREQ = syscall.Errno(0x59) -+ EDOM = syscall.Errno(0x21) -+ EDOTDOT = syscall.Errno(0x49) -+ EDQUOT = syscall.Errno(0x7a) -+ EEXIST = syscall.Errno(0x11) -+ EFAULT = syscall.Errno(0xe) -+ EFBIG = syscall.Errno(0x1b) -+ EHOSTDOWN = syscall.Errno(0x70) -+ EHOSTUNREACH = syscall.Errno(0x71) -+ EHWPOISON = syscall.Errno(0x85) -+ EIDRM = syscall.Errno(0x2b) -+ EILSEQ = syscall.Errno(0x54) -+ EINPROGRESS = syscall.Errno(0x73) -+ EINTR = syscall.Errno(0x4) -+ EINVAL = syscall.Errno(0x16) -+ EIO = syscall.Errno(0x5) -+ EISCONN = syscall.Errno(0x6a) -+ EISDIR = syscall.Errno(0x15) -+ EISNAM = syscall.Errno(0x78) -+ EKEYEXPIRED = syscall.Errno(0x7f) -+ EKEYREJECTED = syscall.Errno(0x81) -+ EKEYREVOKED = syscall.Errno(0x80) -+ EL2HLT = syscall.Errno(0x33) -+ EL2NSYNC = syscall.Errno(0x2d) -+ EL3HLT = syscall.Errno(0x2e) -+ EL3RST = syscall.Errno(0x2f) -+ ELIBACC = syscall.Errno(0x4f) -+ ELIBBAD = syscall.Errno(0x50) -+ ELIBEXEC = syscall.Errno(0x53) -+ ELIBMAX = syscall.Errno(0x52) -+ ELIBSCN = syscall.Errno(0x51) -+ ELNRNG = syscall.Errno(0x30) -+ ELOOP = syscall.Errno(0x28) -+ EMEDIUMTYPE = syscall.Errno(0x7c) -+ EMFILE = syscall.Errno(0x18) -+ EMLINK = syscall.Errno(0x1f) -+ EMSGSIZE = syscall.Errno(0x5a) -+ EMULTIHOP = syscall.Errno(0x48) -+ ENAMETOOLONG = syscall.Errno(0x24) -+ ENAVAIL = syscall.Errno(0x77) -+ ENETDOWN = syscall.Errno(0x64) -+ ENETRESET = syscall.Errno(0x66) -+ ENETUNREACH = syscall.Errno(0x65) -+ ENFILE = syscall.Errno(0x17) -+ ENOANO = syscall.Errno(0x37) -+ ENOBUFS = syscall.Errno(0x69) -+ ENOCSI = syscall.Errno(0x32) -+ ENODATA = syscall.Errno(0x3d) -+ ENODEV = syscall.Errno(0x13) -+ ENOENT = syscall.Errno(0x2) -+ ENOEXEC = syscall.Errno(0x8) -+ ENOKEY = syscall.Errno(0x7e) -+ ENOLCK = syscall.Errno(0x25) -+ ENOLINK = syscall.Errno(0x43) -+ ENOMEDIUM = syscall.Errno(0x7b) -+ ENOMEM = syscall.Errno(0xc) -+ ENOMSG = syscall.Errno(0x2a) -+ ENONET = syscall.Errno(0x40) -+ ENOPKG = syscall.Errno(0x41) -+ ENOPROTOOPT = syscall.Errno(0x5c) -+ ENOSPC = syscall.Errno(0x1c) -+ ENOSR = syscall.Errno(0x3f) -+ ENOSTR = syscall.Errno(0x3c) -+ ENOSYS = syscall.Errno(0x26) -+ ENOTBLK = syscall.Errno(0xf) -+ ENOTCONN = syscall.Errno(0x6b) -+ ENOTDIR = syscall.Errno(0x14) -+ ENOTEMPTY = syscall.Errno(0x27) -+ ENOTNAM = syscall.Errno(0x76) -+ ENOTRECOVERABLE = syscall.Errno(0x83) -+ ENOTSOCK = syscall.Errno(0x58) -+ ENOTSUP = syscall.Errno(0x5f) -+ ENOTTY = syscall.Errno(0x19) -+ ENOTUNIQ = syscall.Errno(0x4c) -+ ENXIO = syscall.Errno(0x6) -+ EOPNOTSUPP = syscall.Errno(0x5f) -+ EOVERFLOW = syscall.Errno(0x4b) -+ EOWNERDEAD = syscall.Errno(0x82) -+ EPERM = syscall.Errno(0x1) -+ EPFNOSUPPORT = syscall.Errno(0x60) -+ EPIPE = syscall.Errno(0x20) -+ EPROTO = syscall.Errno(0x47) -+ EPROTONOSUPPORT = syscall.Errno(0x5d) -+ EPROTOTYPE = syscall.Errno(0x5b) -+ ERANGE = syscall.Errno(0x22) -+ EREMCHG = syscall.Errno(0x4e) -+ EREMOTE = syscall.Errno(0x42) -+ EREMOTEIO = syscall.Errno(0x79) -+ ERESTART = syscall.Errno(0x55) -+ ERFKILL = syscall.Errno(0x84) -+ EROFS = syscall.Errno(0x1e) -+ ESHUTDOWN = syscall.Errno(0x6c) -+ ESOCKTNOSUPPORT = syscall.Errno(0x5e) -+ ESPIPE = syscall.Errno(0x1d) -+ ESRCH = syscall.Errno(0x3) -+ ESRMNT = syscall.Errno(0x45) -+ ESTALE = syscall.Errno(0x74) -+ ESTRPIPE = syscall.Errno(0x56) -+ ETIME = syscall.Errno(0x3e) -+ ETIMEDOUT = syscall.Errno(0x6e) -+ ETOOMANYREFS = syscall.Errno(0x6d) -+ ETXTBSY = syscall.Errno(0x1a) -+ EUCLEAN = syscall.Errno(0x75) -+ EUNATCH = syscall.Errno(0x31) -+ EUSERS = syscall.Errno(0x57) -+ EWOULDBLOCK = syscall.Errno(0xb) -+ EXDEV = syscall.Errno(0x12) -+ EXFULL = syscall.Errno(0x36) -+) -+ -+// Signals -+const ( -+ SIGABRT = syscall.Signal(0x6) -+ SIGALRM = syscall.Signal(0xe) -+ SIGBUS = syscall.Signal(0x7) -+ SIGCHLD = syscall.Signal(0x11) -+ SIGCLD = syscall.Signal(0x11) -+ SIGCONT = syscall.Signal(0x12) -+ SIGFPE = syscall.Signal(0x8) -+ SIGHUP = syscall.Signal(0x1) -+ SIGILL = syscall.Signal(0x4) -+ SIGINT = syscall.Signal(0x2) -+ SIGIO = syscall.Signal(0x1d) -+ SIGIOT = syscall.Signal(0x6) -+ SIGKILL = syscall.Signal(0x9) -+ SIGPIPE = syscall.Signal(0xd) -+ SIGPOLL = syscall.Signal(0x1d) -+ SIGPROF = syscall.Signal(0x1b) -+ SIGPWR = syscall.Signal(0x1e) -+ SIGQUIT = syscall.Signal(0x3) -+ SIGSEGV = syscall.Signal(0xb) -+ SIGSTKFLT = syscall.Signal(0x10) -+ SIGSTOP = syscall.Signal(0x13) -+ SIGSYS = syscall.Signal(0x1f) -+ SIGTERM = syscall.Signal(0xf) -+ SIGTRAP = syscall.Signal(0x5) -+ SIGTSTP = syscall.Signal(0x14) -+ SIGTTIN = syscall.Signal(0x15) -+ SIGTTOU = syscall.Signal(0x16) -+ SIGURG = syscall.Signal(0x17) -+ SIGUSR1 = syscall.Signal(0xa) -+ SIGUSR2 = syscall.Signal(0xc) -+ SIGVTALRM = syscall.Signal(0x1a) -+ SIGWINCH = syscall.Signal(0x1c) -+ SIGXCPU = syscall.Signal(0x18) -+ SIGXFSZ = syscall.Signal(0x19) -+) -+ -+// Error table -+var errorList = [...]struct { -+ num syscall.Errno -+ name string -+ desc string -+}{ -+ {1, "EPERM", "operation not permitted"}, -+ {2, "ENOENT", "no such file or directory"}, -+ {3, "ESRCH", "no such process"}, -+ {4, "EINTR", "interrupted system call"}, -+ {5, "EIO", "input/output error"}, -+ {6, "ENXIO", "no such device or address"}, -+ {7, "E2BIG", "argument list too long"}, -+ {8, "ENOEXEC", "exec format error"}, -+ {9, "EBADF", "bad file descriptor"}, -+ {10, "ECHILD", "no child processes"}, -+ {11, "EAGAIN", "resource temporarily unavailable"}, -+ {12, "ENOMEM", "cannot allocate memory"}, -+ {13, "EACCES", "permission denied"}, -+ {14, "EFAULT", "bad address"}, -+ {15, "ENOTBLK", "block device required"}, -+ {16, "EBUSY", "device or resource busy"}, -+ {17, "EEXIST", "file exists"}, -+ {18, "EXDEV", "invalid cross-device link"}, -+ {19, "ENODEV", "no such device"}, -+ {20, "ENOTDIR", "not a directory"}, -+ {21, "EISDIR", "is a directory"}, -+ {22, "EINVAL", "invalid argument"}, -+ {23, "ENFILE", "too many open files in system"}, -+ {24, "EMFILE", "too many open files"}, -+ {25, "ENOTTY", "inappropriate ioctl for device"}, -+ {26, "ETXTBSY", "text file busy"}, -+ {27, "EFBIG", "file too large"}, -+ {28, "ENOSPC", "no space left on device"}, -+ {29, "ESPIPE", "illegal seek"}, -+ {30, "EROFS", "read-only file system"}, -+ {31, "EMLINK", "too many links"}, -+ {32, "EPIPE", "broken pipe"}, -+ {33, "EDOM", "numerical argument out of domain"}, -+ {34, "ERANGE", "numerical result out of range"}, -+ {35, "EDEADLK", "resource deadlock avoided"}, -+ {36, "ENAMETOOLONG", "file name too long"}, -+ {37, "ENOLCK", "no locks available"}, -+ {38, "ENOSYS", "function not implemented"}, -+ {39, "ENOTEMPTY", "directory not empty"}, -+ {40, "ELOOP", "too many levels of symbolic links"}, -+ {42, "ENOMSG", "no message of desired type"}, -+ {43, "EIDRM", "identifier removed"}, -+ {44, "ECHRNG", "channel number out of range"}, -+ {45, "EL2NSYNC", "level 2 not synchronized"}, -+ {46, "EL3HLT", "level 3 halted"}, -+ {47, "EL3RST", "level 3 reset"}, -+ {48, "ELNRNG", "link number out of range"}, -+ {49, "EUNATCH", "protocol driver not attached"}, -+ {50, "ENOCSI", "no CSI structure available"}, -+ {51, "EL2HLT", "level 2 halted"}, -+ {52, "EBADE", "invalid exchange"}, -+ {53, "EBADR", "invalid request descriptor"}, -+ {54, "EXFULL", "exchange full"}, -+ {55, "ENOANO", "no anode"}, -+ {56, "EBADRQC", "invalid request code"}, -+ {57, "EBADSLT", "invalid slot"}, -+ {59, "EBFONT", "bad font file format"}, -+ {60, "ENOSTR", "device not a stream"}, -+ {61, "ENODATA", "no data available"}, -+ {62, "ETIME", "timer expired"}, -+ {63, "ENOSR", "out of streams resources"}, -+ {64, "ENONET", "machine is not on the network"}, -+ {65, "ENOPKG", "package not installed"}, -+ {66, "EREMOTE", "object is remote"}, -+ {67, "ENOLINK", "link has been severed"}, -+ {68, "EADV", "advertise error"}, -+ {69, "ESRMNT", "srmount error"}, -+ {70, "ECOMM", "communication error on send"}, -+ {71, "EPROTO", "protocol error"}, -+ {72, "EMULTIHOP", "multihop attempted"}, -+ {73, "EDOTDOT", "RFS specific error"}, -+ {74, "EBADMSG", "bad message"}, -+ {75, "EOVERFLOW", "value too large for defined data type"}, -+ {76, "ENOTUNIQ", "name not unique on network"}, -+ {77, "EBADFD", "file descriptor in bad state"}, -+ {78, "EREMCHG", "remote address changed"}, -+ {79, "ELIBACC", "can not access a needed shared library"}, -+ {80, "ELIBBAD", "accessing a corrupted shared library"}, -+ {81, "ELIBSCN", ".lib section in a.out corrupted"}, -+ {82, "ELIBMAX", "attempting to link in too many shared libraries"}, -+ {83, "ELIBEXEC", "cannot exec a shared library directly"}, -+ {84, "EILSEQ", "invalid or incomplete multibyte or wide character"}, -+ {85, "ERESTART", "interrupted system call should be restarted"}, -+ {86, "ESTRPIPE", "streams pipe error"}, -+ {87, "EUSERS", "too many users"}, -+ {88, "ENOTSOCK", "socket operation on non-socket"}, -+ {89, "EDESTADDRREQ", "destination address required"}, -+ {90, "EMSGSIZE", "message too long"}, -+ {91, "EPROTOTYPE", "protocol wrong type for socket"}, -+ {92, "ENOPROTOOPT", "protocol not available"}, -+ {93, "EPROTONOSUPPORT", "protocol not supported"}, -+ {94, "ESOCKTNOSUPPORT", "socket type not supported"}, -+ {95, "ENOTSUP", "operation not supported"}, -+ {96, "EPFNOSUPPORT", "protocol family not supported"}, -+ {97, "EAFNOSUPPORT", "address family not supported by protocol"}, -+ {98, "EADDRINUSE", "address already in use"}, -+ {99, "EADDRNOTAVAIL", "cannot assign requested address"}, -+ {100, "ENETDOWN", "network is down"}, -+ {101, "ENETUNREACH", "network is unreachable"}, -+ {102, "ENETRESET", "network dropped connection on reset"}, -+ {103, "ECONNABORTED", "software caused connection abort"}, -+ {104, "ECONNRESET", "connection reset by peer"}, -+ {105, "ENOBUFS", "no buffer space available"}, -+ {106, "EISCONN", "transport endpoint is already connected"}, -+ {107, "ENOTCONN", "transport endpoint is not connected"}, -+ {108, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, -+ {109, "ETOOMANYREFS", "too many references: cannot splice"}, -+ {110, "ETIMEDOUT", "connection timed out"}, -+ {111, "ECONNREFUSED", "connection refused"}, -+ {112, "EHOSTDOWN", "host is down"}, -+ {113, "EHOSTUNREACH", "no route to host"}, -+ {114, "EALREADY", "operation already in progress"}, -+ {115, "EINPROGRESS", "operation now in progress"}, -+ {116, "ESTALE", "stale file handle"}, -+ {117, "EUCLEAN", "structure needs cleaning"}, -+ {118, "ENOTNAM", "not a XENIX named type file"}, -+ {119, "ENAVAIL", "no XENIX semaphores available"}, -+ {120, "EISNAM", "is a named type file"}, -+ {121, "EREMOTEIO", "remote I/O error"}, -+ {122, "EDQUOT", "disk quota exceeded"}, -+ {123, "ENOMEDIUM", "no medium found"}, -+ {124, "EMEDIUMTYPE", "wrong medium type"}, -+ {125, "ECANCELED", "operation canceled"}, -+ {126, "ENOKEY", "required key not available"}, -+ {127, "EKEYEXPIRED", "key has expired"}, -+ {128, "EKEYREVOKED", "key has been revoked"}, -+ {129, "EKEYREJECTED", "key was rejected by service"}, -+ {130, "EOWNERDEAD", "owner died"}, -+ {131, "ENOTRECOVERABLE", "state not recoverable"}, -+ {132, "ERFKILL", "operation not possible due to RF-kill"}, -+ {133, "EHWPOISON", "memory page has hardware error"}, -+} -+ -+// Signal table -+var signalList = [...]struct { -+ num syscall.Signal -+ name string -+ desc string -+}{ -+ {1, "SIGHUP", "hangup"}, -+ {2, "SIGINT", "interrupt"}, -+ {3, "SIGQUIT", "quit"}, -+ {4, "SIGILL", "illegal instruction"}, -+ {5, "SIGTRAP", "trace/breakpoint trap"}, -+ {6, "SIGABRT", "aborted"}, -+ {7, "SIGBUS", "bus error"}, -+ {8, "SIGFPE", "floating point exception"}, -+ {9, "SIGKILL", "killed"}, -+ {10, "SIGUSR1", "user defined signal 1"}, -+ {11, "SIGSEGV", "segmentation fault"}, -+ {12, "SIGUSR2", "user defined signal 2"}, -+ {13, "SIGPIPE", "broken pipe"}, -+ {14, "SIGALRM", "alarm clock"}, -+ {15, "SIGTERM", "terminated"}, -+ {16, "SIGSTKFLT", "stack fault"}, -+ {17, "SIGCHLD", "child exited"}, -+ {18, "SIGCONT", "continued"}, -+ {19, "SIGSTOP", "stopped (signal)"}, -+ {20, "SIGTSTP", "stopped"}, -+ {21, "SIGTTIN", "stopped (tty input)"}, -+ {22, "SIGTTOU", "stopped (tty output)"}, -+ {23, "SIGURG", "urgent I/O condition"}, -+ {24, "SIGXCPU", "CPU time limit exceeded"}, -+ {25, "SIGXFSZ", "file size limit exceeded"}, -+ {26, "SIGVTALRM", "virtual timer expired"}, -+ {27, "SIGPROF", "profiling timer expired"}, -+ {28, "SIGWINCH", "window changed"}, -+ {29, "SIGIO", "I/O possible"}, -+ {30, "SIGPWR", "power failure"}, -+ {31, "SIGSYS", "bad system call"}, -+} -diff --git a/components/engine/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go b/components/engine/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go -new file mode 100644 -index 0000000..996eba5 ---- /dev/null -+++ b/components/engine/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go -@@ -0,0 +1,2188 @@ -+// go run mksyscall.go -tags linux,riscv64 syscall_linux.go syscall_linux_riscv64.go -+// Code generated by the command above; see README.md. DO NOT EDIT. -+ -+// +build linux,riscv64 -+ -+package unix -+ -+import ( -+ "syscall" -+ "unsafe" -+) -+ -+var _ syscall.Errno -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func fchmodat(dirfd int, path string, mode uint32) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func ioctl(fd int, req uint, arg uintptr) (err error) { -+ _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(oldpath) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(newpath) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_LINKAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { -+ r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 unsafe.Pointer -+ if len(buf) > 0 { -+ _p1 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p1 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(oldpath) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(newpath) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Unlinkat(dirfd int, path string, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getcwd(buf []byte) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { -+ r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) -+ wpid = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func KeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) { -+ r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) -+ ret = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func KeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(_p0), uintptr(len(buf)), uintptr(arg5), 0) -+ ret = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func keyctlJoin(cmd int, arg2 string) (ret int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(arg2) -+ if err != nil { -+ return -+ } -+ r0, _, e1 := Syscall(SYS_KEYCTL, uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0) -+ ret = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func keyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(arg3) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(arg4) -+ if err != nil { -+ return -+ } -+ r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(arg5), 0) -+ ret = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func keyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) { -+ var _p0 unsafe.Pointer -+ if len(payload) > 0 { -+ _p0 = unsafe.Pointer(&payload[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(_p0), uintptr(len(payload)), uintptr(arg5), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func keyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(unsafe.Pointer(arg2)), uintptr(_p0), uintptr(len(buf)), 0, 0) -+ ret = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { -+ _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(arg) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(source) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(target) -+ if err != nil { -+ return -+ } -+ var _p2 *byte -+ _p2, err = BytePtrFromString(fstype) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Acct(path string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(keyType) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(description) -+ if err != nil { -+ return -+ } -+ var _p2 unsafe.Pointer -+ if len(payload) > 0 { -+ _p2 = unsafe.Pointer(&payload[0]) -+ } else { -+ _p2 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_ADD_KEY, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(payload)), uintptr(ringid), 0) -+ id = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Adjtimex(buf *Timex) (state int, err error) { -+ r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0) -+ state = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Chdir(path string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Chroot(path string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func ClockGetres(clockid int32, res *Timespec) (err error) { -+ _, _, e1 := Syscall(SYS_CLOCK_GETRES, uintptr(clockid), uintptr(unsafe.Pointer(res)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func ClockGettime(clockid int32, time *Timespec) (err error) { -+ _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { -+ _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Close(fd int) (err error) { -+ _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) { -+ r0, _, e1 := Syscall6(SYS_COPY_FILE_RANGE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func DeleteModule(name string, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(name) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Dup(oldfd int) (fd int, err error) { -+ r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Dup3(oldfd int, newfd int, flags int) (err error) { -+ _, _, e1 := Syscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func EpollCreate1(flag int) (fd int, err error) { -+ r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { -+ _, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Eventfd(initval uint, flags int) (fd int, err error) { -+ r0, _, e1 := Syscall(SYS_EVENTFD2, uintptr(initval), uintptr(flags), 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Exit(code int) { -+ SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { -+ _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fchdir(fd int) (err error) { -+ _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fchmod(fd int, mode uint32) (err error) { -+ _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func fcntl(fd int, cmd int, arg int) (val int, err error) { -+ r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg)) -+ val = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fdatasync(fd int) (err error) { -+ _, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p1 unsafe.Pointer -+ if len(dest) > 0 { -+ _p1 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p1 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func FinitModule(fd int, params string, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(params) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Flistxattr(fd int, dest []byte) (sz int, err error) { -+ var _p0 unsafe.Pointer -+ if len(dest) > 0 { -+ _p0 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Flock(fd int, how int) (err error) { -+ _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fremovexattr(fd int, attr string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p1 unsafe.Pointer -+ if len(dest) > 0 { -+ _p1 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p1 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fsync(fd int) (err error) { -+ _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getdents(fd int, buf []byte) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf))) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getpgid(pid int) (pgid int, err error) { -+ r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0) -+ pgid = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getpid() (pid int) { -+ r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) -+ pid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getppid() (ppid int) { -+ r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) -+ ppid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getpriority(which int, who int) (prio int, err error) { -+ r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0) -+ prio = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getrandom(buf []byte, flags int) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_GETRANDOM, uintptr(_p0), uintptr(len(buf)), uintptr(flags)) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getrusage(who int, rusage *Rusage) (err error) { -+ _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getsid(pid int) (sid int, err error) { -+ r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) -+ sid = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Gettid() (tid int) { -+ r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) -+ tid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getxattr(path string, attr string, dest []byte) (sz int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p2 unsafe.Pointer -+ if len(dest) > 0 { -+ _p2 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p2 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func InitModule(moduleImage []byte, params string) (err error) { -+ var _p0 unsafe.Pointer -+ if len(moduleImage) > 0 { -+ _p0 = unsafe.Pointer(&moduleImage[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(params) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1))) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(pathname) -+ if err != nil { -+ return -+ } -+ r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask)) -+ watchdesc = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func InotifyInit1(flags int) (fd int, err error) { -+ r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) { -+ r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0) -+ success = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Kill(pid int, sig syscall.Signal) (err error) { -+ _, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Klogctl(typ int, buf []byte) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf))) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Lgetxattr(path string, attr string, dest []byte) (sz int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p2 unsafe.Pointer -+ if len(dest) > 0 { -+ _p2 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p2 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_LGETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Listxattr(path string, dest []byte) (sz int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 unsafe.Pointer -+ if len(dest) > 0 { -+ _p1 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p1 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest))) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Llistxattr(path string, dest []byte) (sz int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 unsafe.Pointer -+ if len(dest) > 0 { -+ _p1 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p1 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_LLISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest))) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Lremovexattr(path string, attr string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_LREMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Lsetxattr(path string, attr string, data []byte, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p2 unsafe.Pointer -+ if len(data) > 0 { -+ _p2 = unsafe.Pointer(&data[0]) -+ } else { -+ _p2 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall6(SYS_LSETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func MemfdCreate(name string, flags int) (fd int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(name) -+ if err != nil { -+ return -+ } -+ r0, _, e1 := Syscall(SYS_MEMFD_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Mkdirat(dirfd int, path string, mode uint32) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Nanosleep(time *Timespec, leftover *Timespec) (err error) { -+ _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { -+ r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func PivotRoot(newroot string, putold string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(newroot) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(putold) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { -+ _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) { -+ _, _, e1 := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { -+ r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func read(fd int, p []byte) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Removexattr(path string, attr string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(oldpath) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(newpath) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(keyType) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(description) -+ if err != nil { -+ return -+ } -+ var _p2 *byte -+ _p2, err = BytePtrFromString(callback) -+ if err != nil { -+ return -+ } -+ r0, _, e1 := Syscall6(SYS_REQUEST_KEY, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(destRingid), 0, 0) -+ id = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setdomainname(p []byte) (err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Sethostname(p []byte) (err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setpgid(pid int, pgid int) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setsid() (pid int, err error) { -+ r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) -+ pid = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Settimeofday(tv *Timeval) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setns(fd int, nstype int) (err error) { -+ _, _, e1 := Syscall(SYS_SETNS, uintptr(fd), uintptr(nstype), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setpriority(which int, who int, prio int) (err error) { -+ _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setxattr(path string, attr string, data []byte, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p2 unsafe.Pointer -+ if len(data) > 0 { -+ _p2 = unsafe.Pointer(&data[0]) -+ } else { -+ _p2 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Signalfd(fd int, mask *Sigset_t, flags int) { -+ SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Sync() { -+ SyscallNoError(SYS_SYNC, 0, 0, 0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Syncfs(fd int) (err error) { -+ _, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Sysinfo(info *Sysinfo_t) (err error) { -+ _, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) { -+ r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0) -+ n = int64(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) { -+ _, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Times(tms *Tms) (ticks uintptr, err error) { -+ r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0) -+ ticks = uintptr(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Umask(mask int) (oldmask int) { -+ r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) -+ oldmask = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Uname(buf *Utsname) (err error) { -+ _, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Unmount(target string, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(target) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Unshare(flags int) (err error) { -+ _, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func write(fd int, p []byte) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p))) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func exitThread(code int) (err error) { -+ _, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func readlen(fd int, p *byte, np int) (n int, err error) { -+ r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np)) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func writelen(fd int, p *byte, np int) (n int, err error) { -+ r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np)) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func munmap(addr uintptr, length uintptr) (err error) { -+ _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Madvise(b []byte, advice int) (err error) { -+ var _p0 unsafe.Pointer -+ if len(b) > 0 { -+ _p0 = unsafe.Pointer(&b[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Mprotect(b []byte, prot int) (err error) { -+ var _p0 unsafe.Pointer -+ if len(b) > 0 { -+ _p0 = unsafe.Pointer(&b[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Mlock(b []byte) (err error) { -+ var _p0 unsafe.Pointer -+ if len(b) > 0 { -+ _p0 = unsafe.Pointer(&b[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Mlockall(flags int) (err error) { -+ _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Msync(b []byte, flags int) (err error) { -+ var _p0 unsafe.Pointer -+ if len(b) > 0 { -+ _p0 = unsafe.Pointer(&b[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Munlock(b []byte) (err error) { -+ var _p0 unsafe.Pointer -+ if len(b) > 0 { -+ _p0 = unsafe.Pointer(&b[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Munlockall() (err error) { -+ _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func faccessat(dirfd int, path string, mode uint32) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(events) > 0 { -+ _p0 = unsafe.Pointer(&events[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_EPOLL_PWAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fadvise(fd int, offset int64, length int64, advice int) (err error) { -+ _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fchown(fd int, uid int, gid int) (err error) { -+ _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fstat(fd int, stat *Stat_t) (err error) { -+ _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fstatfs(fd int, buf *Statfs_t) (err error) { -+ _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Ftruncate(fd int, length int64) (err error) { -+ _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getegid() (egid int) { -+ r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) -+ egid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Geteuid() (euid int) { -+ r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) -+ euid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getgid() (gid int) { -+ r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) -+ gid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getrlimit(resource int, rlim *Rlimit) (err error) { -+ _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getuid() (uid int) { -+ r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) -+ uid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Listen(s int, n int) (err error) { -+ _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Pread(fd int, p []byte, offset int64) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Pwrite(fd int, p []byte, offset int64) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Seek(fd int, offset int64, whence int) (off int64, err error) { -+ r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) -+ off = int64(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { -+ r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) -+ written = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setfsgid(gid int) (err error) { -+ _, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setfsuid(uid int) (err error) { -+ _, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setregid(rgid int, egid int) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setresgid(rgid int, egid int, sgid int) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setresuid(ruid int, euid int, suid int) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setrlimit(resource int, rlim *Rlimit) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setreuid(ruid int, euid int) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Shutdown(fd int, how int) (err error) { -+ _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) { -+ r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) -+ n = int64(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Statfs(path string, buf *Statfs_t) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func SyncFileRange(fd int, off int64, n int64, flags int) (err error) { -+ _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Truncate(path string, length int64) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { -+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) { -+ r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { -+ _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { -+ _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func getgroups(n int, list *_Gid_t) (nn int, err error) { -+ r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0) -+ nn = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func setgroups(n int, list *_Gid_t) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { -+ _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { -+ _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func socket(domain int, typ int, proto int) (fd int, err error) { -+ r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto)) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { -+ _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { -+ _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { -+ _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { -+ r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { -+ r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { -+ r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)) -+ xaddr = uintptr(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Gettimeofday(tv *Timeval) (err error) { -+ _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func pipe2(p *[2]_C_int, flags int) (err error) { -+ _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -diff --git a/components/engine/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/components/engine/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go -new file mode 100644 -index 0000000..473c746 ---- /dev/null -+++ b/components/engine/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go -@@ -0,0 +1,287 @@ -+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h -+// Code generated by the command above; see README.md. DO NOT EDIT. -+ -+// +build riscv64,linux -+ -+package unix -+ -+const ( -+ SYS_IO_SETUP = 0 -+ SYS_IO_DESTROY = 1 -+ SYS_IO_SUBMIT = 2 -+ SYS_IO_CANCEL = 3 -+ SYS_IO_GETEVENTS = 4 -+ SYS_SETXATTR = 5 -+ SYS_LSETXATTR = 6 -+ SYS_FSETXATTR = 7 -+ SYS_GETXATTR = 8 -+ SYS_LGETXATTR = 9 -+ SYS_FGETXATTR = 10 -+ SYS_LISTXATTR = 11 -+ SYS_LLISTXATTR = 12 -+ SYS_FLISTXATTR = 13 -+ SYS_REMOVEXATTR = 14 -+ SYS_LREMOVEXATTR = 15 -+ SYS_FREMOVEXATTR = 16 -+ SYS_GETCWD = 17 -+ SYS_LOOKUP_DCOOKIE = 18 -+ SYS_EVENTFD2 = 19 -+ SYS_EPOLL_CREATE1 = 20 -+ SYS_EPOLL_CTL = 21 -+ SYS_EPOLL_PWAIT = 22 -+ SYS_DUP = 23 -+ SYS_DUP3 = 24 -+ SYS_FCNTL = 25 -+ SYS_INOTIFY_INIT1 = 26 -+ SYS_INOTIFY_ADD_WATCH = 27 -+ SYS_INOTIFY_RM_WATCH = 28 -+ SYS_IOCTL = 29 -+ SYS_IOPRIO_SET = 30 -+ SYS_IOPRIO_GET = 31 -+ SYS_FLOCK = 32 -+ SYS_MKNODAT = 33 -+ SYS_MKDIRAT = 34 -+ SYS_UNLINKAT = 35 -+ SYS_SYMLINKAT = 36 -+ SYS_LINKAT = 37 -+ SYS_UMOUNT2 = 39 -+ SYS_MOUNT = 40 -+ SYS_PIVOT_ROOT = 41 -+ SYS_NFSSERVCTL = 42 -+ SYS_STATFS = 43 -+ SYS_FSTATFS = 44 -+ SYS_TRUNCATE = 45 -+ SYS_FTRUNCATE = 46 -+ SYS_FALLOCATE = 47 -+ SYS_FACCESSAT = 48 -+ SYS_CHDIR = 49 -+ SYS_FCHDIR = 50 -+ SYS_CHROOT = 51 -+ SYS_FCHMOD = 52 -+ SYS_FCHMODAT = 53 -+ SYS_FCHOWNAT = 54 -+ SYS_FCHOWN = 55 -+ SYS_OPENAT = 56 -+ SYS_CLOSE = 57 -+ SYS_VHANGUP = 58 -+ SYS_PIPE2 = 59 -+ SYS_QUOTACTL = 60 -+ SYS_GETDENTS64 = 61 -+ SYS_LSEEK = 62 -+ SYS_READ = 63 -+ SYS_WRITE = 64 -+ SYS_READV = 65 -+ SYS_WRITEV = 66 -+ SYS_PREAD64 = 67 -+ SYS_PWRITE64 = 68 -+ SYS_PREADV = 69 -+ SYS_PWRITEV = 70 -+ SYS_SENDFILE = 71 -+ SYS_PSELECT6 = 72 -+ SYS_PPOLL = 73 -+ SYS_SIGNALFD4 = 74 -+ SYS_VMSPLICE = 75 -+ SYS_SPLICE = 76 -+ SYS_TEE = 77 -+ SYS_READLINKAT = 78 -+ SYS_FSTATAT = 79 -+ SYS_FSTAT = 80 -+ SYS_SYNC = 81 -+ SYS_FSYNC = 82 -+ SYS_FDATASYNC = 83 -+ SYS_SYNC_FILE_RANGE = 84 -+ SYS_TIMERFD_CREATE = 85 -+ SYS_TIMERFD_SETTIME = 86 -+ SYS_TIMERFD_GETTIME = 87 -+ SYS_UTIMENSAT = 88 -+ SYS_ACCT = 89 -+ SYS_CAPGET = 90 -+ SYS_CAPSET = 91 -+ SYS_PERSONALITY = 92 -+ SYS_EXIT = 93 -+ SYS_EXIT_GROUP = 94 -+ SYS_WAITID = 95 -+ SYS_SET_TID_ADDRESS = 96 -+ SYS_UNSHARE = 97 -+ SYS_FUTEX = 98 -+ SYS_SET_ROBUST_LIST = 99 -+ SYS_GET_ROBUST_LIST = 100 -+ SYS_NANOSLEEP = 101 -+ SYS_GETITIMER = 102 -+ SYS_SETITIMER = 103 -+ SYS_KEXEC_LOAD = 104 -+ SYS_INIT_MODULE = 105 -+ SYS_DELETE_MODULE = 106 -+ SYS_TIMER_CREATE = 107 -+ SYS_TIMER_GETTIME = 108 -+ SYS_TIMER_GETOVERRUN = 109 -+ SYS_TIMER_SETTIME = 110 -+ SYS_TIMER_DELETE = 111 -+ SYS_CLOCK_SETTIME = 112 -+ SYS_CLOCK_GETTIME = 113 -+ SYS_CLOCK_GETRES = 114 -+ SYS_CLOCK_NANOSLEEP = 115 -+ SYS_SYSLOG = 116 -+ SYS_PTRACE = 117 -+ SYS_SCHED_SETPARAM = 118 -+ SYS_SCHED_SETSCHEDULER = 119 -+ SYS_SCHED_GETSCHEDULER = 120 -+ SYS_SCHED_GETPARAM = 121 -+ SYS_SCHED_SETAFFINITY = 122 -+ SYS_SCHED_GETAFFINITY = 123 -+ SYS_SCHED_YIELD = 124 -+ SYS_SCHED_GET_PRIORITY_MAX = 125 -+ SYS_SCHED_GET_PRIORITY_MIN = 126 -+ SYS_SCHED_RR_GET_INTERVAL = 127 -+ SYS_RESTART_SYSCALL = 128 -+ SYS_KILL = 129 -+ SYS_TKILL = 130 -+ SYS_TGKILL = 131 -+ SYS_SIGALTSTACK = 132 -+ SYS_RT_SIGSUSPEND = 133 -+ SYS_RT_SIGACTION = 134 -+ SYS_RT_SIGPROCMASK = 135 -+ SYS_RT_SIGPENDING = 136 -+ SYS_RT_SIGTIMEDWAIT = 137 -+ SYS_RT_SIGQUEUEINFO = 138 -+ SYS_RT_SIGRETURN = 139 -+ SYS_SETPRIORITY = 140 -+ SYS_GETPRIORITY = 141 -+ SYS_REBOOT = 142 -+ SYS_SETREGID = 143 -+ SYS_SETGID = 144 -+ SYS_SETREUID = 145 -+ SYS_SETUID = 146 -+ SYS_SETRESUID = 147 -+ SYS_GETRESUID = 148 -+ SYS_SETRESGID = 149 -+ SYS_GETRESGID = 150 -+ SYS_SETFSUID = 151 -+ SYS_SETFSGID = 152 -+ SYS_TIMES = 153 -+ SYS_SETPGID = 154 -+ SYS_GETPGID = 155 -+ SYS_GETSID = 156 -+ SYS_SETSID = 157 -+ SYS_GETGROUPS = 158 -+ SYS_SETGROUPS = 159 -+ SYS_UNAME = 160 -+ SYS_SETHOSTNAME = 161 -+ SYS_SETDOMAINNAME = 162 -+ SYS_GETRLIMIT = 163 -+ SYS_SETRLIMIT = 164 -+ SYS_GETRUSAGE = 165 -+ SYS_UMASK = 166 -+ SYS_PRCTL = 167 -+ SYS_GETCPU = 168 -+ SYS_GETTIMEOFDAY = 169 -+ SYS_SETTIMEOFDAY = 170 -+ SYS_ADJTIMEX = 171 -+ SYS_GETPID = 172 -+ SYS_GETPPID = 173 -+ SYS_GETUID = 174 -+ SYS_GETEUID = 175 -+ SYS_GETGID = 176 -+ SYS_GETEGID = 177 -+ SYS_GETTID = 178 -+ SYS_SYSINFO = 179 -+ SYS_MQ_OPEN = 180 -+ SYS_MQ_UNLINK = 181 -+ SYS_MQ_TIMEDSEND = 182 -+ SYS_MQ_TIMEDRECEIVE = 183 -+ SYS_MQ_NOTIFY = 184 -+ SYS_MQ_GETSETATTR = 185 -+ SYS_MSGGET = 186 -+ SYS_MSGCTL = 187 -+ SYS_MSGRCV = 188 -+ SYS_MSGSND = 189 -+ SYS_SEMGET = 190 -+ SYS_SEMCTL = 191 -+ SYS_SEMTIMEDOP = 192 -+ SYS_SEMOP = 193 -+ SYS_SHMGET = 194 -+ SYS_SHMCTL = 195 -+ SYS_SHMAT = 196 -+ SYS_SHMDT = 197 -+ SYS_SOCKET = 198 -+ SYS_SOCKETPAIR = 199 -+ SYS_BIND = 200 -+ SYS_LISTEN = 201 -+ SYS_ACCEPT = 202 -+ SYS_CONNECT = 203 -+ SYS_GETSOCKNAME = 204 -+ SYS_GETPEERNAME = 205 -+ SYS_SENDTO = 206 -+ SYS_RECVFROM = 207 -+ SYS_SETSOCKOPT = 208 -+ SYS_GETSOCKOPT = 209 -+ SYS_SHUTDOWN = 210 -+ SYS_SENDMSG = 211 -+ SYS_RECVMSG = 212 -+ SYS_READAHEAD = 213 -+ SYS_BRK = 214 -+ SYS_MUNMAP = 215 -+ SYS_MREMAP = 216 -+ SYS_ADD_KEY = 217 -+ SYS_REQUEST_KEY = 218 -+ SYS_KEYCTL = 219 -+ SYS_CLONE = 220 -+ SYS_EXECVE = 221 -+ SYS_MMAP = 222 -+ SYS_FADVISE64 = 223 -+ SYS_SWAPON = 224 -+ SYS_SWAPOFF = 225 -+ SYS_MPROTECT = 226 -+ SYS_MSYNC = 227 -+ SYS_MLOCK = 228 -+ SYS_MUNLOCK = 229 -+ SYS_MLOCKALL = 230 -+ SYS_MUNLOCKALL = 231 -+ SYS_MINCORE = 232 -+ SYS_MADVISE = 233 -+ SYS_REMAP_FILE_PAGES = 234 -+ SYS_MBIND = 235 -+ SYS_GET_MEMPOLICY = 236 -+ SYS_SET_MEMPOLICY = 237 -+ SYS_MIGRATE_PAGES = 238 -+ SYS_MOVE_PAGES = 239 -+ SYS_RT_TGSIGQUEUEINFO = 240 -+ SYS_PERF_EVENT_OPEN = 241 -+ SYS_ACCEPT4 = 242 -+ SYS_RECVMMSG = 243 -+ SYS_ARCH_SPECIFIC_SYSCALL = 244 -+ SYS_WAIT4 = 260 -+ SYS_PRLIMIT64 = 261 -+ SYS_FANOTIFY_INIT = 262 -+ SYS_FANOTIFY_MARK = 263 -+ SYS_NAME_TO_HANDLE_AT = 264 -+ SYS_OPEN_BY_HANDLE_AT = 265 -+ SYS_CLOCK_ADJTIME = 266 -+ SYS_SYNCFS = 267 -+ SYS_SETNS = 268 -+ SYS_SENDMMSG = 269 -+ SYS_PROCESS_VM_READV = 270 -+ SYS_PROCESS_VM_WRITEV = 271 -+ SYS_KCMP = 272 -+ SYS_FINIT_MODULE = 273 -+ SYS_SCHED_SETATTR = 274 -+ SYS_SCHED_GETATTR = 275 -+ SYS_RENAMEAT2 = 276 -+ SYS_SECCOMP = 277 -+ SYS_GETRANDOM = 278 -+ SYS_MEMFD_CREATE = 279 -+ SYS_BPF = 280 -+ SYS_EXECVEAT = 281 -+ SYS_USERFAULTFD = 282 -+ SYS_MEMBARRIER = 283 -+ SYS_MLOCK2 = 284 -+ SYS_COPY_FILE_RANGE = 285 -+ SYS_PREADV2 = 286 -+ SYS_PWRITEV2 = 287 -+ SYS_PKEY_MPROTECT = 288 -+ SYS_PKEY_ALLOC = 289 -+ SYS_PKEY_FREE = 290 -+ SYS_STATX = 291 -+ SYS_IO_PGETEVENTS = 292 -+ SYS_RSEQ = 293 -+) -diff --git a/components/engine/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/components/engine/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go -new file mode 100644 -index 0000000..f6d02d7 ---- /dev/null -+++ b/components/engine/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go -@@ -0,0 +1,2046 @@ -+// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go -+// Code generated by the command above; see README.md. DO NOT EDIT. -+ -+// +build riscv64,linux -+ -+package unix -+ -+const ( -+ sizeofPtr = 0x8 -+ sizeofShort = 0x2 -+ sizeofInt = 0x4 -+ sizeofLong = 0x8 -+ sizeofLongLong = 0x8 -+ PathMax = 0x1000 -+) -+ -+type ( -+ _C_short int16 -+ _C_int int32 -+ _C_long int64 -+ _C_long_long int64 -+) -+ -+type Timespec struct { -+ Sec int64 -+ Nsec int64 -+} -+ -+type Timeval struct { -+ Sec int64 -+ Usec int64 -+} -+ -+type Timex struct { -+ Modes uint32 -+ Offset int64 -+ Freq int64 -+ Maxerror int64 -+ Esterror int64 -+ Status int32 -+ Constant int64 -+ Precision int64 -+ Tolerance int64 -+ Time Timeval -+ Tick int64 -+ Ppsfreq int64 -+ Jitter int64 -+ Shift int32 -+ Stabil int64 -+ Jitcnt int64 -+ Calcnt int64 -+ Errcnt int64 -+ Stbcnt int64 -+ Tai int32 -+ _ [44]byte -+} -+ -+type Time_t int64 -+ -+type Tms struct { -+ Utime int64 -+ Stime int64 -+ Cutime int64 -+ Cstime int64 -+} -+ -+type Utimbuf struct { -+ Actime int64 -+ Modtime int64 -+} -+ -+type Rusage struct { -+ Utime Timeval -+ Stime Timeval -+ Maxrss int64 -+ Ixrss int64 -+ Idrss int64 -+ Isrss int64 -+ Minflt int64 -+ Majflt int64 -+ Nswap int64 -+ Inblock int64 -+ Oublock int64 -+ Msgsnd int64 -+ Msgrcv int64 -+ Nsignals int64 -+ Nvcsw int64 -+ Nivcsw int64 -+} -+ -+type Rlimit struct { -+ Cur uint64 -+ Max uint64 -+} -+ -+type _Gid_t uint32 -+ -+type Stat_t struct { -+ Dev uint64 -+ Ino uint64 -+ Mode uint32 -+ Nlink uint32 -+ Uid uint32 -+ Gid uint32 -+ Rdev uint64 -+ _ uint64 -+ Size int64 -+ Blksize int32 -+ _ int32 -+ Blocks int64 -+ Atim Timespec -+ Mtim Timespec -+ Ctim Timespec -+ _ [2]int32 -+} -+ -+type StatxTimestamp struct { -+ Sec int64 -+ Nsec uint32 -+ _ int32 -+} -+ -+type Statx_t struct { -+ Mask uint32 -+ Blksize uint32 -+ Attributes uint64 -+ Nlink uint32 -+ Uid uint32 -+ Gid uint32 -+ Mode uint16 -+ _ [1]uint16 -+ Ino uint64 -+ Size uint64 -+ Blocks uint64 -+ Attributes_mask uint64 -+ Atime StatxTimestamp -+ Btime StatxTimestamp -+ Ctime StatxTimestamp -+ Mtime StatxTimestamp -+ Rdev_major uint32 -+ Rdev_minor uint32 -+ Dev_major uint32 -+ Dev_minor uint32 -+ _ [14]uint64 -+} -+ -+type Dirent struct { -+ Ino uint64 -+ Off int64 -+ Reclen uint16 -+ Type uint8 -+ Name [256]uint8 -+ _ [5]byte -+} -+ -+type Fsid struct { -+ Val [2]int32 -+} -+ -+type Flock_t struct { -+ Type int16 -+ Whence int16 -+ Start int64 -+ Len int64 -+ Pid int32 -+ _ [4]byte -+} -+ -+type FscryptPolicy struct { -+ Version uint8 -+ Contents_encryption_mode uint8 -+ Filenames_encryption_mode uint8 -+ Flags uint8 -+ Master_key_descriptor [8]uint8 -+} -+ -+type FscryptKey struct { -+ Mode uint32 -+ Raw [64]uint8 -+ Size uint32 -+} -+ -+type KeyctlDHParams struct { -+ Private int32 -+ Prime int32 -+ Base int32 -+} -+ -+const ( -+ FADV_NORMAL = 0x0 -+ FADV_RANDOM = 0x1 -+ FADV_SEQUENTIAL = 0x2 -+ FADV_WILLNEED = 0x3 -+ FADV_DONTNEED = 0x4 -+ FADV_NOREUSE = 0x5 -+) -+ -+type RawSockaddrInet4 struct { -+ Family uint16 -+ Port uint16 -+ Addr [4]byte /* in_addr */ -+ Zero [8]uint8 -+} -+ -+type RawSockaddrInet6 struct { -+ Family uint16 -+ Port uint16 -+ Flowinfo uint32 -+ Addr [16]byte /* in6_addr */ -+ Scope_id uint32 -+} -+ -+type RawSockaddrUnix struct { -+ Family uint16 -+ Path [108]int8 -+} -+ -+type RawSockaddrLinklayer struct { -+ Family uint16 -+ Protocol uint16 -+ Ifindex int32 -+ Hatype uint16 -+ Pkttype uint8 -+ Halen uint8 -+ Addr [8]uint8 -+} -+ -+type RawSockaddrNetlink struct { -+ Family uint16 -+ Pad uint16 -+ Pid uint32 -+ Groups uint32 -+} -+ -+type RawSockaddrHCI struct { -+ Family uint16 -+ Dev uint16 -+ Channel uint16 -+} -+ -+type RawSockaddrL2 struct { -+ Family uint16 -+ Psm uint16 -+ Bdaddr [6]uint8 -+ Cid uint16 -+ Bdaddr_type uint8 -+ _ [1]byte -+} -+ -+type RawSockaddrRFCOMM struct { -+ Family uint16 -+ Bdaddr [6]uint8 -+ Channel uint8 -+ _ [1]byte -+} -+ -+type RawSockaddrCAN struct { -+ Family uint16 -+ Ifindex int32 -+ Addr [8]byte -+} -+ -+type RawSockaddrALG struct { -+ Family uint16 -+ Type [14]uint8 -+ Feat uint32 -+ Mask uint32 -+ Name [64]uint8 -+} -+ -+type RawSockaddrVM struct { -+ Family uint16 -+ Reserved1 uint16 -+ Port uint32 -+ Cid uint32 -+ Zero [4]uint8 -+} -+ -+type RawSockaddrXDP struct { -+ Family uint16 -+ Flags uint16 -+ Ifindex uint32 -+ Queue_id uint32 -+ Shared_umem_fd uint32 -+} -+ -+type RawSockaddrPPPoX [0x1e]byte -+ -+type RawSockaddr struct { -+ Family uint16 -+ Data [14]uint8 -+} -+ -+type RawSockaddrAny struct { -+ Addr RawSockaddr -+ Pad [96]uint8 -+} -+ -+type _Socklen uint32 -+ -+type Linger struct { -+ Onoff int32 -+ Linger int32 -+} -+ -+type Iovec struct { -+ Base *byte -+ Len uint64 -+} -+ -+type IPMreq struct { -+ Multiaddr [4]byte /* in_addr */ -+ Interface [4]byte /* in_addr */ -+} -+ -+type IPMreqn struct { -+ Multiaddr [4]byte /* in_addr */ -+ Address [4]byte /* in_addr */ -+ Ifindex int32 -+} -+ -+type IPv6Mreq struct { -+ Multiaddr [16]byte /* in6_addr */ -+ Interface uint32 -+} -+ -+type PacketMreq struct { -+ Ifindex int32 -+ Type uint16 -+ Alen uint16 -+ Address [8]uint8 -+} -+ -+type Msghdr struct { -+ Name *byte -+ Namelen uint32 -+ Iov *Iovec -+ Iovlen uint64 -+ Control *byte -+ Controllen uint64 -+ Flags int32 -+ _ [4]byte -+} -+ -+type Cmsghdr struct { -+ Len uint64 -+ Level int32 -+ Type int32 -+} -+ -+type Inet4Pktinfo struct { -+ Ifindex int32 -+ Spec_dst [4]byte /* in_addr */ -+ Addr [4]byte /* in_addr */ -+} -+ -+type Inet6Pktinfo struct { -+ Addr [16]byte /* in6_addr */ -+ Ifindex uint32 -+} -+ -+type IPv6MTUInfo struct { -+ Addr RawSockaddrInet6 -+ Mtu uint32 -+} -+ -+type ICMPv6Filter struct { -+ Data [8]uint32 -+} -+ -+type Ucred struct { -+ Pid int32 -+ Uid uint32 -+ Gid uint32 -+} -+ -+type TCPInfo struct { -+ State uint8 -+ Ca_state uint8 -+ Retransmits uint8 -+ Probes uint8 -+ Backoff uint8 -+ Options uint8 -+ Rto uint32 -+ Ato uint32 -+ Snd_mss uint32 -+ Rcv_mss uint32 -+ Unacked uint32 -+ Sacked uint32 -+ Lost uint32 -+ Retrans uint32 -+ Fackets uint32 -+ Last_data_sent uint32 -+ Last_ack_sent uint32 -+ Last_data_recv uint32 -+ Last_ack_recv uint32 -+ Pmtu uint32 -+ Rcv_ssthresh uint32 -+ Rtt uint32 -+ Rttvar uint32 -+ Snd_ssthresh uint32 -+ Snd_cwnd uint32 -+ Advmss uint32 -+ Reordering uint32 -+ Rcv_rtt uint32 -+ Rcv_space uint32 -+ Total_retrans uint32 -+} -+ -+const ( -+ SizeofSockaddrInet4 = 0x10 -+ SizeofSockaddrInet6 = 0x1c -+ SizeofSockaddrAny = 0x70 -+ SizeofSockaddrUnix = 0x6e -+ SizeofSockaddrLinklayer = 0x14 -+ SizeofSockaddrNetlink = 0xc -+ SizeofSockaddrHCI = 0x6 -+ SizeofSockaddrL2 = 0xe -+ SizeofSockaddrRFCOMM = 0xa -+ SizeofSockaddrCAN = 0x10 -+ SizeofSockaddrALG = 0x58 -+ SizeofSockaddrVM = 0x10 -+ SizeofSockaddrXDP = 0x10 -+ SizeofSockaddrPPPoX = 0x1e -+ SizeofLinger = 0x8 -+ SizeofIovec = 0x10 -+ SizeofIPMreq = 0x8 -+ SizeofIPMreqn = 0xc -+ SizeofIPv6Mreq = 0x14 -+ SizeofPacketMreq = 0x10 -+ SizeofMsghdr = 0x38 -+ SizeofCmsghdr = 0x10 -+ SizeofInet4Pktinfo = 0xc -+ SizeofInet6Pktinfo = 0x14 -+ SizeofIPv6MTUInfo = 0x20 -+ SizeofICMPv6Filter = 0x20 -+ SizeofUcred = 0xc -+ SizeofTCPInfo = 0x68 -+) -+ -+const ( -+ IFA_UNSPEC = 0x0 -+ IFA_ADDRESS = 0x1 -+ IFA_LOCAL = 0x2 -+ IFA_LABEL = 0x3 -+ IFA_BROADCAST = 0x4 -+ IFA_ANYCAST = 0x5 -+ IFA_CACHEINFO = 0x6 -+ IFA_MULTICAST = 0x7 -+ IFLA_UNSPEC = 0x0 -+ IFLA_ADDRESS = 0x1 -+ IFLA_BROADCAST = 0x2 -+ IFLA_IFNAME = 0x3 -+ IFLA_INFO_KIND = 0x1 -+ IFLA_MTU = 0x4 -+ IFLA_LINK = 0x5 -+ IFLA_QDISC = 0x6 -+ IFLA_STATS = 0x7 -+ IFLA_COST = 0x8 -+ IFLA_PRIORITY = 0x9 -+ IFLA_MASTER = 0xa -+ IFLA_WIRELESS = 0xb -+ IFLA_PROTINFO = 0xc -+ IFLA_TXQLEN = 0xd -+ IFLA_MAP = 0xe -+ IFLA_WEIGHT = 0xf -+ IFLA_OPERSTATE = 0x10 -+ IFLA_LINKMODE = 0x11 -+ IFLA_LINKINFO = 0x12 -+ IFLA_NET_NS_PID = 0x13 -+ IFLA_IFALIAS = 0x14 -+ IFLA_NUM_VF = 0x15 -+ IFLA_VFINFO_LIST = 0x16 -+ IFLA_STATS64 = 0x17 -+ IFLA_VF_PORTS = 0x18 -+ IFLA_PORT_SELF = 0x19 -+ IFLA_AF_SPEC = 0x1a -+ IFLA_GROUP = 0x1b -+ IFLA_NET_NS_FD = 0x1c -+ IFLA_EXT_MASK = 0x1d -+ IFLA_PROMISCUITY = 0x1e -+ IFLA_NUM_TX_QUEUES = 0x1f -+ IFLA_NUM_RX_QUEUES = 0x20 -+ IFLA_CARRIER = 0x21 -+ IFLA_PHYS_PORT_ID = 0x22 -+ IFLA_CARRIER_CHANGES = 0x23 -+ IFLA_PHYS_SWITCH_ID = 0x24 -+ IFLA_LINK_NETNSID = 0x25 -+ IFLA_PHYS_PORT_NAME = 0x26 -+ IFLA_PROTO_DOWN = 0x27 -+ IFLA_GSO_MAX_SEGS = 0x28 -+ IFLA_GSO_MAX_SIZE = 0x29 -+ IFLA_PAD = 0x2a -+ IFLA_XDP = 0x2b -+ IFLA_EVENT = 0x2c -+ IFLA_NEW_NETNSID = 0x2d -+ IFLA_IF_NETNSID = 0x2e -+ IFLA_MAX = 0x33 -+ RT_SCOPE_UNIVERSE = 0x0 -+ RT_SCOPE_SITE = 0xc8 -+ RT_SCOPE_LINK = 0xfd -+ RT_SCOPE_HOST = 0xfe -+ RT_SCOPE_NOWHERE = 0xff -+ RT_TABLE_UNSPEC = 0x0 -+ RT_TABLE_COMPAT = 0xfc -+ RT_TABLE_DEFAULT = 0xfd -+ RT_TABLE_MAIN = 0xfe -+ RT_TABLE_LOCAL = 0xff -+ RT_TABLE_MAX = 0xffffffff -+ RTA_UNSPEC = 0x0 -+ RTA_DST = 0x1 -+ RTA_SRC = 0x2 -+ RTA_IIF = 0x3 -+ RTA_OIF = 0x4 -+ RTA_GATEWAY = 0x5 -+ RTA_PRIORITY = 0x6 -+ RTA_PREFSRC = 0x7 -+ RTA_METRICS = 0x8 -+ RTA_MULTIPATH = 0x9 -+ RTA_FLOW = 0xb -+ RTA_CACHEINFO = 0xc -+ RTA_TABLE = 0xf -+ RTA_MARK = 0x10 -+ RTA_MFC_STATS = 0x11 -+ RTA_VIA = 0x12 -+ RTA_NEWDST = 0x13 -+ RTA_PREF = 0x14 -+ RTA_ENCAP_TYPE = 0x15 -+ RTA_ENCAP = 0x16 -+ RTA_EXPIRES = 0x17 -+ RTA_PAD = 0x18 -+ RTA_UID = 0x19 -+ RTA_TTL_PROPAGATE = 0x1a -+ RTA_IP_PROTO = 0x1b -+ RTA_SPORT = 0x1c -+ RTA_DPORT = 0x1d -+ RTN_UNSPEC = 0x0 -+ RTN_UNICAST = 0x1 -+ RTN_LOCAL = 0x2 -+ RTN_BROADCAST = 0x3 -+ RTN_ANYCAST = 0x4 -+ RTN_MULTICAST = 0x5 -+ RTN_BLACKHOLE = 0x6 -+ RTN_UNREACHABLE = 0x7 -+ RTN_PROHIBIT = 0x8 -+ RTN_THROW = 0x9 -+ RTN_NAT = 0xa -+ RTN_XRESOLVE = 0xb -+ RTNLGRP_NONE = 0x0 -+ RTNLGRP_LINK = 0x1 -+ RTNLGRP_NOTIFY = 0x2 -+ RTNLGRP_NEIGH = 0x3 -+ RTNLGRP_TC = 0x4 -+ RTNLGRP_IPV4_IFADDR = 0x5 -+ RTNLGRP_IPV4_MROUTE = 0x6 -+ RTNLGRP_IPV4_ROUTE = 0x7 -+ RTNLGRP_IPV4_RULE = 0x8 -+ RTNLGRP_IPV6_IFADDR = 0x9 -+ RTNLGRP_IPV6_MROUTE = 0xa -+ RTNLGRP_IPV6_ROUTE = 0xb -+ RTNLGRP_IPV6_IFINFO = 0xc -+ RTNLGRP_IPV6_PREFIX = 0x12 -+ RTNLGRP_IPV6_RULE = 0x13 -+ RTNLGRP_ND_USEROPT = 0x14 -+ SizeofNlMsghdr = 0x10 -+ SizeofNlMsgerr = 0x14 -+ SizeofRtGenmsg = 0x1 -+ SizeofNlAttr = 0x4 -+ SizeofRtAttr = 0x4 -+ SizeofIfInfomsg = 0x10 -+ SizeofIfAddrmsg = 0x8 -+ SizeofRtMsg = 0xc -+ SizeofRtNexthop = 0x8 -+) -+ -+type NlMsghdr struct { -+ Len uint32 -+ Type uint16 -+ Flags uint16 -+ Seq uint32 -+ Pid uint32 -+} -+ -+type NlMsgerr struct { -+ Error int32 -+ Msg NlMsghdr -+} -+ -+type RtGenmsg struct { -+ Family uint8 -+} -+ -+type NlAttr struct { -+ Len uint16 -+ Type uint16 -+} -+ -+type RtAttr struct { -+ Len uint16 -+ Type uint16 -+} -+ -+type IfInfomsg struct { -+ Family uint8 -+ _ uint8 -+ Type uint16 -+ Index int32 -+ Flags uint32 -+ Change uint32 -+} -+ -+type IfAddrmsg struct { -+ Family uint8 -+ Prefixlen uint8 -+ Flags uint8 -+ Scope uint8 -+ Index uint32 -+} -+ -+type RtMsg struct { -+ Family uint8 -+ Dst_len uint8 -+ Src_len uint8 -+ Tos uint8 -+ Table uint8 -+ Protocol uint8 -+ Scope uint8 -+ Type uint8 -+ Flags uint32 -+} -+ -+type RtNexthop struct { -+ Len uint16 -+ Flags uint8 -+ Hops uint8 -+ Ifindex int32 -+} -+ -+const ( -+ SizeofSockFilter = 0x8 -+ SizeofSockFprog = 0x10 -+) -+ -+type SockFilter struct { -+ Code uint16 -+ Jt uint8 -+ Jf uint8 -+ K uint32 -+} -+ -+type SockFprog struct { -+ Len uint16 -+ Filter *SockFilter -+} -+ -+type InotifyEvent struct { -+ Wd int32 -+ Mask uint32 -+ Cookie uint32 -+ Len uint32 -+} -+ -+const SizeofInotifyEvent = 0x10 -+ -+type PtraceRegs struct { -+ Pc uint64 -+ Ra uint64 -+ Sp uint64 -+ Gp uint64 -+ Tp uint64 -+ T0 uint64 -+ T1 uint64 -+ T2 uint64 -+ S0 uint64 -+ S1 uint64 -+ A0 uint64 -+ A1 uint64 -+ A2 uint64 -+ A3 uint64 -+ A4 uint64 -+ A5 uint64 -+ A6 uint64 -+ A7 uint64 -+ S2 uint64 -+ S3 uint64 -+ S4 uint64 -+ S5 uint64 -+ S6 uint64 -+ S7 uint64 -+ S8 uint64 -+ S9 uint64 -+ S10 uint64 -+ S11 uint64 -+ T3 uint64 -+ T4 uint64 -+ T5 uint64 -+ T6 uint64 -+} -+ -+type FdSet struct { -+ Bits [16]int64 -+} -+ -+type Sysinfo_t struct { -+ Uptime int64 -+ Loads [3]uint64 -+ Totalram uint64 -+ Freeram uint64 -+ Sharedram uint64 -+ Bufferram uint64 -+ Totalswap uint64 -+ Freeswap uint64 -+ Procs uint16 -+ Pad uint16 -+ Totalhigh uint64 -+ Freehigh uint64 -+ Unit uint32 -+ _ [0]uint8 -+ _ [4]byte -+} -+ -+type Utsname struct { -+ Sysname [65]byte -+ Nodename [65]byte -+ Release [65]byte -+ Version [65]byte -+ Machine [65]byte -+ Domainname [65]byte -+} -+ -+type Ustat_t struct { -+ Tfree int32 -+ Tinode uint64 -+ Fname [6]uint8 -+ Fpack [6]uint8 -+ _ [4]byte -+} -+ -+type EpollEvent struct { -+ Events uint32 -+ Fd int32 -+ Pad int32 -+} -+ -+const ( -+ AT_EMPTY_PATH = 0x1000 -+ AT_FDCWD = -0x64 -+ AT_NO_AUTOMOUNT = 0x800 -+ AT_REMOVEDIR = 0x200 -+ -+ AT_STATX_SYNC_AS_STAT = 0x0 -+ AT_STATX_FORCE_SYNC = 0x2000 -+ AT_STATX_DONT_SYNC = 0x4000 -+ -+ AT_SYMLINK_FOLLOW = 0x400 -+ AT_SYMLINK_NOFOLLOW = 0x100 -+ -+ AT_EACCESS = 0x200 -+) -+ -+type PollFd struct { -+ Fd int32 -+ Events int16 -+ Revents int16 -+} -+ -+const ( -+ POLLIN = 0x1 -+ POLLPRI = 0x2 -+ POLLOUT = 0x4 -+ POLLRDHUP = 0x2000 -+ POLLERR = 0x8 -+ POLLHUP = 0x10 -+ POLLNVAL = 0x20 -+) -+ -+type Sigset_t struct { -+ Val [16]uint64 -+} -+ -+type SignalfdSiginfo struct { -+ Signo uint32 -+ Errno int32 -+ Code int32 -+ Pid uint32 -+ Uid uint32 -+ Fd int32 -+ Tid uint32 -+ Band uint32 -+ Overrun uint32 -+ Trapno uint32 -+ Status int32 -+ Int int32 -+ Ptr uint64 -+ Utime uint64 -+ Stime uint64 -+ Addr uint64 -+ Addr_lsb uint16 -+ _ uint16 -+ Syscall int32 -+ Call_addr uint64 -+ Arch uint32 -+ _ [28]uint8 -+} -+ -+const PERF_IOC_FLAG_GROUP = 0x1 -+ -+type Termios struct { -+ Iflag uint32 -+ Oflag uint32 -+ Cflag uint32 -+ Lflag uint32 -+ Line uint8 -+ Cc [19]uint8 -+ Ispeed uint32 -+ Ospeed uint32 -+} -+ -+type Winsize struct { -+ Row uint16 -+ Col uint16 -+ Xpixel uint16 -+ Ypixel uint16 -+} -+ -+type Taskstats struct { -+ Version uint16 -+ Ac_exitcode uint32 -+ Ac_flag uint8 -+ Ac_nice uint8 -+ Cpu_count uint64 -+ Cpu_delay_total uint64 -+ Blkio_count uint64 -+ Blkio_delay_total uint64 -+ Swapin_count uint64 -+ Swapin_delay_total uint64 -+ Cpu_run_real_total uint64 -+ Cpu_run_virtual_total uint64 -+ Ac_comm [32]uint8 -+ Ac_sched uint8 -+ Ac_pad [3]uint8 -+ _ [4]byte -+ Ac_uid uint32 -+ Ac_gid uint32 -+ Ac_pid uint32 -+ Ac_ppid uint32 -+ Ac_btime uint32 -+ Ac_etime uint64 -+ Ac_utime uint64 -+ Ac_stime uint64 -+ Ac_minflt uint64 -+ Ac_majflt uint64 -+ Coremem uint64 -+ Virtmem uint64 -+ Hiwater_rss uint64 -+ Hiwater_vm uint64 -+ Read_char uint64 -+ Write_char uint64 -+ Read_syscalls uint64 -+ Write_syscalls uint64 -+ Read_bytes uint64 -+ Write_bytes uint64 -+ Cancelled_write_bytes uint64 -+ Nvcsw uint64 -+ Nivcsw uint64 -+ Ac_utimescaled uint64 -+ Ac_stimescaled uint64 -+ Cpu_scaled_run_real_total uint64 -+ Freepages_count uint64 -+ Freepages_delay_total uint64 -+ Thrashing_count uint64 -+ Thrashing_delay_total uint64 -+} -+ -+const ( -+ TASKSTATS_CMD_UNSPEC = 0x0 -+ TASKSTATS_CMD_GET = 0x1 -+ TASKSTATS_CMD_NEW = 0x2 -+ TASKSTATS_TYPE_UNSPEC = 0x0 -+ TASKSTATS_TYPE_PID = 0x1 -+ TASKSTATS_TYPE_TGID = 0x2 -+ TASKSTATS_TYPE_STATS = 0x3 -+ TASKSTATS_TYPE_AGGR_PID = 0x4 -+ TASKSTATS_TYPE_AGGR_TGID = 0x5 -+ TASKSTATS_TYPE_NULL = 0x6 -+ TASKSTATS_CMD_ATTR_UNSPEC = 0x0 -+ TASKSTATS_CMD_ATTR_PID = 0x1 -+ TASKSTATS_CMD_ATTR_TGID = 0x2 -+ TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 -+ TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 -+) -+ -+type CGroupStats struct { -+ Sleeping uint64 -+ Running uint64 -+ Stopped uint64 -+ Uninterruptible uint64 -+ Io_wait uint64 -+} -+ -+const ( -+ CGROUPSTATS_CMD_UNSPEC = 0x3 -+ CGROUPSTATS_CMD_GET = 0x4 -+ CGROUPSTATS_CMD_NEW = 0x5 -+ CGROUPSTATS_TYPE_UNSPEC = 0x0 -+ CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 -+ CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 -+ CGROUPSTATS_CMD_ATTR_FD = 0x1 -+) -+ -+type Genlmsghdr struct { -+ Cmd uint8 -+ Version uint8 -+ Reserved uint16 -+} -+ -+const ( -+ CTRL_CMD_UNSPEC = 0x0 -+ CTRL_CMD_NEWFAMILY = 0x1 -+ CTRL_CMD_DELFAMILY = 0x2 -+ CTRL_CMD_GETFAMILY = 0x3 -+ CTRL_CMD_NEWOPS = 0x4 -+ CTRL_CMD_DELOPS = 0x5 -+ CTRL_CMD_GETOPS = 0x6 -+ CTRL_CMD_NEWMCAST_GRP = 0x7 -+ CTRL_CMD_DELMCAST_GRP = 0x8 -+ CTRL_CMD_GETMCAST_GRP = 0x9 -+ CTRL_ATTR_UNSPEC = 0x0 -+ CTRL_ATTR_FAMILY_ID = 0x1 -+ CTRL_ATTR_FAMILY_NAME = 0x2 -+ CTRL_ATTR_VERSION = 0x3 -+ CTRL_ATTR_HDRSIZE = 0x4 -+ CTRL_ATTR_MAXATTR = 0x5 -+ CTRL_ATTR_OPS = 0x6 -+ CTRL_ATTR_MCAST_GROUPS = 0x7 -+ CTRL_ATTR_OP_UNSPEC = 0x0 -+ CTRL_ATTR_OP_ID = 0x1 -+ CTRL_ATTR_OP_FLAGS = 0x2 -+ CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 -+ CTRL_ATTR_MCAST_GRP_NAME = 0x1 -+ CTRL_ATTR_MCAST_GRP_ID = 0x2 -+) -+ -+type cpuMask uint64 -+ -+const ( -+ _CPU_SETSIZE = 0x400 -+ _NCPUBITS = 0x40 -+) -+ -+const ( -+ BDADDR_BREDR = 0x0 -+ BDADDR_LE_PUBLIC = 0x1 -+ BDADDR_LE_RANDOM = 0x2 -+) -+ -+type PerfEventAttr struct { -+ Type uint32 -+ Size uint32 -+ Config uint64 -+ Sample uint64 -+ Sample_type uint64 -+ Read_format uint64 -+ Bits uint64 -+ Wakeup uint32 -+ Bp_type uint32 -+ Ext1 uint64 -+ Ext2 uint64 -+ Branch_sample_type uint64 -+ Sample_regs_user uint64 -+ Sample_stack_user uint32 -+ Clockid int32 -+ Sample_regs_intr uint64 -+ Aux_watermark uint32 -+ _ uint32 -+} -+ -+type PerfEventMmapPage struct { -+ Version uint32 -+ Compat_version uint32 -+ Lock uint32 -+ Index uint32 -+ Offset int64 -+ Time_enabled uint64 -+ Time_running uint64 -+ Capabilities uint64 -+ Pmc_width uint16 -+ Time_shift uint16 -+ Time_mult uint32 -+ Time_offset uint64 -+ Time_zero uint64 -+ Size uint32 -+ _ [948]uint8 -+ Data_head uint64 -+ Data_tail uint64 -+ Data_offset uint64 -+ Data_size uint64 -+ Aux_head uint64 -+ Aux_tail uint64 -+ Aux_offset uint64 -+ Aux_size uint64 -+} -+ -+const ( -+ PerfBitDisabled uint64 = CBitFieldMaskBit0 -+ PerfBitInherit = CBitFieldMaskBit1 -+ PerfBitPinned = CBitFieldMaskBit2 -+ PerfBitExclusive = CBitFieldMaskBit3 -+ PerfBitExcludeUser = CBitFieldMaskBit4 -+ PerfBitExcludeKernel = CBitFieldMaskBit5 -+ PerfBitExcludeHv = CBitFieldMaskBit6 -+ PerfBitExcludeIdle = CBitFieldMaskBit7 -+ PerfBitMmap = CBitFieldMaskBit8 -+ PerfBitComm = CBitFieldMaskBit9 -+ PerfBitFreq = CBitFieldMaskBit10 -+ PerfBitInheritStat = CBitFieldMaskBit11 -+ PerfBitEnableOnExec = CBitFieldMaskBit12 -+ PerfBitTask = CBitFieldMaskBit13 -+ PerfBitWatermark = CBitFieldMaskBit14 -+ PerfBitPreciseIPBit1 = CBitFieldMaskBit15 -+ PerfBitPreciseIPBit2 = CBitFieldMaskBit16 -+ PerfBitMmapData = CBitFieldMaskBit17 -+ PerfBitSampleIDAll = CBitFieldMaskBit18 -+ PerfBitExcludeHost = CBitFieldMaskBit19 -+ PerfBitExcludeGuest = CBitFieldMaskBit20 -+ PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 -+ PerfBitExcludeCallchainUser = CBitFieldMaskBit22 -+ PerfBitMmap2 = CBitFieldMaskBit23 -+ PerfBitCommExec = CBitFieldMaskBit24 -+ PerfBitUseClockID = CBitFieldMaskBit25 -+ PerfBitContextSwitch = CBitFieldMaskBit26 -+) -+ -+const ( -+ PERF_TYPE_HARDWARE = 0x0 -+ PERF_TYPE_SOFTWARE = 0x1 -+ PERF_TYPE_TRACEPOINT = 0x2 -+ PERF_TYPE_HW_CACHE = 0x3 -+ PERF_TYPE_RAW = 0x4 -+ PERF_TYPE_BREAKPOINT = 0x5 -+ -+ PERF_COUNT_HW_CPU_CYCLES = 0x0 -+ PERF_COUNT_HW_INSTRUCTIONS = 0x1 -+ PERF_COUNT_HW_CACHE_REFERENCES = 0x2 -+ PERF_COUNT_HW_CACHE_MISSES = 0x3 -+ PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 -+ PERF_COUNT_HW_BRANCH_MISSES = 0x5 -+ PERF_COUNT_HW_BUS_CYCLES = 0x6 -+ PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 -+ PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 -+ PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 -+ -+ PERF_COUNT_HW_CACHE_L1D = 0x0 -+ PERF_COUNT_HW_CACHE_L1I = 0x1 -+ PERF_COUNT_HW_CACHE_LL = 0x2 -+ PERF_COUNT_HW_CACHE_DTLB = 0x3 -+ PERF_COUNT_HW_CACHE_ITLB = 0x4 -+ PERF_COUNT_HW_CACHE_BPU = 0x5 -+ PERF_COUNT_HW_CACHE_NODE = 0x6 -+ -+ PERF_COUNT_HW_CACHE_OP_READ = 0x0 -+ PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 -+ PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 -+ -+ PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 -+ PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 -+ -+ PERF_COUNT_SW_CPU_CLOCK = 0x0 -+ PERF_COUNT_SW_TASK_CLOCK = 0x1 -+ PERF_COUNT_SW_PAGE_FAULTS = 0x2 -+ PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 -+ PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 -+ PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 -+ PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 -+ PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 -+ PERF_COUNT_SW_EMULATION_FAULTS = 0x8 -+ PERF_COUNT_SW_DUMMY = 0x9 -+ -+ PERF_SAMPLE_IP = 0x1 -+ PERF_SAMPLE_TID = 0x2 -+ PERF_SAMPLE_TIME = 0x4 -+ PERF_SAMPLE_ADDR = 0x8 -+ PERF_SAMPLE_READ = 0x10 -+ PERF_SAMPLE_CALLCHAIN = 0x20 -+ PERF_SAMPLE_ID = 0x40 -+ PERF_SAMPLE_CPU = 0x80 -+ PERF_SAMPLE_PERIOD = 0x100 -+ PERF_SAMPLE_STREAM_ID = 0x200 -+ PERF_SAMPLE_RAW = 0x400 -+ PERF_SAMPLE_BRANCH_STACK = 0x800 -+ -+ PERF_SAMPLE_BRANCH_USER = 0x1 -+ PERF_SAMPLE_BRANCH_KERNEL = 0x2 -+ PERF_SAMPLE_BRANCH_HV = 0x4 -+ PERF_SAMPLE_BRANCH_ANY = 0x8 -+ PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 -+ PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 -+ PERF_SAMPLE_BRANCH_IND_CALL = 0x40 -+ -+ PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 -+ PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 -+ PERF_FORMAT_ID = 0x4 -+ PERF_FORMAT_GROUP = 0x8 -+ -+ PERF_RECORD_MMAP = 0x1 -+ PERF_RECORD_LOST = 0x2 -+ PERF_RECORD_COMM = 0x3 -+ PERF_RECORD_EXIT = 0x4 -+ PERF_RECORD_THROTTLE = 0x5 -+ PERF_RECORD_UNTHROTTLE = 0x6 -+ PERF_RECORD_FORK = 0x7 -+ PERF_RECORD_READ = 0x8 -+ PERF_RECORD_SAMPLE = 0x9 -+ -+ PERF_CONTEXT_HV = -0x20 -+ PERF_CONTEXT_KERNEL = -0x80 -+ PERF_CONTEXT_USER = -0x200 -+ -+ PERF_CONTEXT_GUEST = -0x800 -+ PERF_CONTEXT_GUEST_KERNEL = -0x880 -+ PERF_CONTEXT_GUEST_USER = -0xa00 -+ -+ PERF_FLAG_FD_NO_GROUP = 0x1 -+ PERF_FLAG_FD_OUTPUT = 0x2 -+ PERF_FLAG_PID_CGROUP = 0x4 -+) -+ -+const ( -+ CBitFieldMaskBit0 = 0x1 -+ CBitFieldMaskBit1 = 0x2 -+ CBitFieldMaskBit2 = 0x4 -+ CBitFieldMaskBit3 = 0x8 -+ CBitFieldMaskBit4 = 0x10 -+ CBitFieldMaskBit5 = 0x20 -+ CBitFieldMaskBit6 = 0x40 -+ CBitFieldMaskBit7 = 0x80 -+ CBitFieldMaskBit8 = 0x100 -+ CBitFieldMaskBit9 = 0x200 -+ CBitFieldMaskBit10 = 0x400 -+ CBitFieldMaskBit11 = 0x800 -+ CBitFieldMaskBit12 = 0x1000 -+ CBitFieldMaskBit13 = 0x2000 -+ CBitFieldMaskBit14 = 0x4000 -+ CBitFieldMaskBit15 = 0x8000 -+ CBitFieldMaskBit16 = 0x10000 -+ CBitFieldMaskBit17 = 0x20000 -+ CBitFieldMaskBit18 = 0x40000 -+ CBitFieldMaskBit19 = 0x80000 -+ CBitFieldMaskBit20 = 0x100000 -+ CBitFieldMaskBit21 = 0x200000 -+ CBitFieldMaskBit22 = 0x400000 -+ CBitFieldMaskBit23 = 0x800000 -+ CBitFieldMaskBit24 = 0x1000000 -+ CBitFieldMaskBit25 = 0x2000000 -+ CBitFieldMaskBit26 = 0x4000000 -+ CBitFieldMaskBit27 = 0x8000000 -+ CBitFieldMaskBit28 = 0x10000000 -+ CBitFieldMaskBit29 = 0x20000000 -+ CBitFieldMaskBit30 = 0x40000000 -+ CBitFieldMaskBit31 = 0x80000000 -+ CBitFieldMaskBit32 = 0x100000000 -+ CBitFieldMaskBit33 = 0x200000000 -+ CBitFieldMaskBit34 = 0x400000000 -+ CBitFieldMaskBit35 = 0x800000000 -+ CBitFieldMaskBit36 = 0x1000000000 -+ CBitFieldMaskBit37 = 0x2000000000 -+ CBitFieldMaskBit38 = 0x4000000000 -+ CBitFieldMaskBit39 = 0x8000000000 -+ CBitFieldMaskBit40 = 0x10000000000 -+ CBitFieldMaskBit41 = 0x20000000000 -+ CBitFieldMaskBit42 = 0x40000000000 -+ CBitFieldMaskBit43 = 0x80000000000 -+ CBitFieldMaskBit44 = 0x100000000000 -+ CBitFieldMaskBit45 = 0x200000000000 -+ CBitFieldMaskBit46 = 0x400000000000 -+ CBitFieldMaskBit47 = 0x800000000000 -+ CBitFieldMaskBit48 = 0x1000000000000 -+ CBitFieldMaskBit49 = 0x2000000000000 -+ CBitFieldMaskBit50 = 0x4000000000000 -+ CBitFieldMaskBit51 = 0x8000000000000 -+ CBitFieldMaskBit52 = 0x10000000000000 -+ CBitFieldMaskBit53 = 0x20000000000000 -+ CBitFieldMaskBit54 = 0x40000000000000 -+ CBitFieldMaskBit55 = 0x80000000000000 -+ CBitFieldMaskBit56 = 0x100000000000000 -+ CBitFieldMaskBit57 = 0x200000000000000 -+ CBitFieldMaskBit58 = 0x400000000000000 -+ CBitFieldMaskBit59 = 0x800000000000000 -+ CBitFieldMaskBit60 = 0x1000000000000000 -+ CBitFieldMaskBit61 = 0x2000000000000000 -+ CBitFieldMaskBit62 = 0x4000000000000000 -+ CBitFieldMaskBit63 = 0x8000000000000000 -+) -+ -+type SockaddrStorage struct { -+ Family uint16 -+ _ [118]uint8 -+ _ uint64 -+} -+ -+type TCPMD5Sig struct { -+ Addr SockaddrStorage -+ Flags uint8 -+ Prefixlen uint8 -+ Keylen uint16 -+ _ uint32 -+ Key [80]uint8 -+} -+ -+type HDDriveCmdHdr struct { -+ Command uint8 -+ Number uint8 -+ Feature uint8 -+ Count uint8 -+} -+ -+type HDGeometry struct { -+ Heads uint8 -+ Sectors uint8 -+ Cylinders uint16 -+ Start uint64 -+} -+ -+type HDDriveID struct { -+ Config uint16 -+ Cyls uint16 -+ Reserved2 uint16 -+ Heads uint16 -+ Track_bytes uint16 -+ Sector_bytes uint16 -+ Sectors uint16 -+ Vendor0 uint16 -+ Vendor1 uint16 -+ Vendor2 uint16 -+ Serial_no [20]uint8 -+ Buf_type uint16 -+ Buf_size uint16 -+ Ecc_bytes uint16 -+ Fw_rev [8]uint8 -+ Model [40]uint8 -+ Max_multsect uint8 -+ Vendor3 uint8 -+ Dword_io uint16 -+ Vendor4 uint8 -+ Capability uint8 -+ Reserved50 uint16 -+ Vendor5 uint8 -+ TPIO uint8 -+ Vendor6 uint8 -+ TDMA uint8 -+ Field_valid uint16 -+ Cur_cyls uint16 -+ Cur_heads uint16 -+ Cur_sectors uint16 -+ Cur_capacity0 uint16 -+ Cur_capacity1 uint16 -+ Multsect uint8 -+ Multsect_valid uint8 -+ Lba_capacity uint32 -+ Dma_1word uint16 -+ Dma_mword uint16 -+ Eide_pio_modes uint16 -+ Eide_dma_min uint16 -+ Eide_dma_time uint16 -+ Eide_pio uint16 -+ Eide_pio_iordy uint16 -+ Words69_70 [2]uint16 -+ Words71_74 [4]uint16 -+ Queue_depth uint16 -+ Words76_79 [4]uint16 -+ Major_rev_num uint16 -+ Minor_rev_num uint16 -+ Command_set_1 uint16 -+ Command_set_2 uint16 -+ Cfsse uint16 -+ Cfs_enable_1 uint16 -+ Cfs_enable_2 uint16 -+ Csf_default uint16 -+ Dma_ultra uint16 -+ Trseuc uint16 -+ TrsEuc uint16 -+ CurAPMvalues uint16 -+ Mprc uint16 -+ Hw_config uint16 -+ Acoustic uint16 -+ Msrqs uint16 -+ Sxfert uint16 -+ Sal uint16 -+ Spg uint32 -+ Lba_capacity_2 uint64 -+ Words104_125 [22]uint16 -+ Last_lun uint16 -+ Word127 uint16 -+ Dlf uint16 -+ Csfo uint16 -+ Words130_155 [26]uint16 -+ Word156 uint16 -+ Words157_159 [3]uint16 -+ Cfa_power uint16 -+ Words161_175 [15]uint16 -+ Words176_205 [30]uint16 -+ Words206_254 [49]uint16 -+ Integrity_word uint16 -+} -+ -+type Statfs_t struct { -+ Type int64 -+ Bsize int64 -+ Blocks uint64 -+ Bfree uint64 -+ Bavail uint64 -+ Files uint64 -+ Ffree uint64 -+ Fsid Fsid -+ Namelen int64 -+ Frsize int64 -+ Flags int64 -+ Spare [4]int64 -+} -+ -+const ( -+ ST_MANDLOCK = 0x40 -+ ST_NOATIME = 0x400 -+ ST_NODEV = 0x4 -+ ST_NODIRATIME = 0x800 -+ ST_NOEXEC = 0x8 -+ ST_NOSUID = 0x2 -+ ST_RDONLY = 0x1 -+ ST_RELATIME = 0x1000 -+ ST_SYNCHRONOUS = 0x10 -+) -+ -+type TpacketHdr struct { -+ Status uint64 -+ Len uint32 -+ Snaplen uint32 -+ Mac uint16 -+ Net uint16 -+ Sec uint32 -+ Usec uint32 -+ _ [4]byte -+} -+ -+type Tpacket2Hdr struct { -+ Status uint32 -+ Len uint32 -+ Snaplen uint32 -+ Mac uint16 -+ Net uint16 -+ Sec uint32 -+ Nsec uint32 -+ Vlan_tci uint16 -+ Vlan_tpid uint16 -+ _ [4]uint8 -+} -+ -+type Tpacket3Hdr struct { -+ Next_offset uint32 -+ Sec uint32 -+ Nsec uint32 -+ Snaplen uint32 -+ Len uint32 -+ Status uint32 -+ Mac uint16 -+ Net uint16 -+ Hv1 TpacketHdrVariant1 -+ _ [8]uint8 -+} -+ -+type TpacketHdrVariant1 struct { -+ Rxhash uint32 -+ Vlan_tci uint32 -+ Vlan_tpid uint16 -+ _ uint16 -+} -+ -+type TpacketBlockDesc struct { -+ Version uint32 -+ To_priv uint32 -+ Hdr [40]byte -+} -+ -+type TpacketReq struct { -+ Block_size uint32 -+ Block_nr uint32 -+ Frame_size uint32 -+ Frame_nr uint32 -+} -+ -+type TpacketReq3 struct { -+ Block_size uint32 -+ Block_nr uint32 -+ Frame_size uint32 -+ Frame_nr uint32 -+ Retire_blk_tov uint32 -+ Sizeof_priv uint32 -+ Feature_req_word uint32 -+} -+ -+type TpacketStats struct { -+ Packets uint32 -+ Drops uint32 -+} -+ -+type TpacketStatsV3 struct { -+ Packets uint32 -+ Drops uint32 -+ Freeze_q_cnt uint32 -+} -+ -+type TpacketAuxdata struct { -+ Status uint32 -+ Len uint32 -+ Snaplen uint32 -+ Mac uint16 -+ Net uint16 -+ Vlan_tci uint16 -+ Vlan_tpid uint16 -+} -+ -+const ( -+ TPACKET_V1 = 0x0 -+ TPACKET_V2 = 0x1 -+ TPACKET_V3 = 0x2 -+) -+ -+const ( -+ SizeofTpacketHdr = 0x20 -+ SizeofTpacket2Hdr = 0x20 -+ SizeofTpacket3Hdr = 0x30 -+) -+ -+const ( -+ NF_INET_PRE_ROUTING = 0x0 -+ NF_INET_LOCAL_IN = 0x1 -+ NF_INET_FORWARD = 0x2 -+ NF_INET_LOCAL_OUT = 0x3 -+ NF_INET_POST_ROUTING = 0x4 -+ NF_INET_NUMHOOKS = 0x5 -+) -+ -+const ( -+ NF_NETDEV_INGRESS = 0x0 -+ NF_NETDEV_NUMHOOKS = 0x1 -+) -+ -+const ( -+ NFPROTO_UNSPEC = 0x0 -+ NFPROTO_INET = 0x1 -+ NFPROTO_IPV4 = 0x2 -+ NFPROTO_ARP = 0x3 -+ NFPROTO_NETDEV = 0x5 -+ NFPROTO_BRIDGE = 0x7 -+ NFPROTO_IPV6 = 0xa -+ NFPROTO_DECNET = 0xc -+ NFPROTO_NUMPROTO = 0xd -+) -+ -+type Nfgenmsg struct { -+ Nfgen_family uint8 -+ Version uint8 -+ Res_id uint16 -+} -+ -+const ( -+ NFNL_BATCH_UNSPEC = 0x0 -+ NFNL_BATCH_GENID = 0x1 -+) -+ -+const ( -+ NFT_REG_VERDICT = 0x0 -+ NFT_REG_1 = 0x1 -+ NFT_REG_2 = 0x2 -+ NFT_REG_3 = 0x3 -+ NFT_REG_4 = 0x4 -+ NFT_REG32_00 = 0x8 -+ NFT_REG32_01 = 0x9 -+ NFT_REG32_02 = 0xa -+ NFT_REG32_03 = 0xb -+ NFT_REG32_04 = 0xc -+ NFT_REG32_05 = 0xd -+ NFT_REG32_06 = 0xe -+ NFT_REG32_07 = 0xf -+ NFT_REG32_08 = 0x10 -+ NFT_REG32_09 = 0x11 -+ NFT_REG32_10 = 0x12 -+ NFT_REG32_11 = 0x13 -+ NFT_REG32_12 = 0x14 -+ NFT_REG32_13 = 0x15 -+ NFT_REG32_14 = 0x16 -+ NFT_REG32_15 = 0x17 -+ NFT_CONTINUE = -0x1 -+ NFT_BREAK = -0x2 -+ NFT_JUMP = -0x3 -+ NFT_GOTO = -0x4 -+ NFT_RETURN = -0x5 -+ NFT_MSG_NEWTABLE = 0x0 -+ NFT_MSG_GETTABLE = 0x1 -+ NFT_MSG_DELTABLE = 0x2 -+ NFT_MSG_NEWCHAIN = 0x3 -+ NFT_MSG_GETCHAIN = 0x4 -+ NFT_MSG_DELCHAIN = 0x5 -+ NFT_MSG_NEWRULE = 0x6 -+ NFT_MSG_GETRULE = 0x7 -+ NFT_MSG_DELRULE = 0x8 -+ NFT_MSG_NEWSET = 0x9 -+ NFT_MSG_GETSET = 0xa -+ NFT_MSG_DELSET = 0xb -+ NFT_MSG_NEWSETELEM = 0xc -+ NFT_MSG_GETSETELEM = 0xd -+ NFT_MSG_DELSETELEM = 0xe -+ NFT_MSG_NEWGEN = 0xf -+ NFT_MSG_GETGEN = 0x10 -+ NFT_MSG_TRACE = 0x11 -+ NFT_MSG_NEWOBJ = 0x12 -+ NFT_MSG_GETOBJ = 0x13 -+ NFT_MSG_DELOBJ = 0x14 -+ NFT_MSG_GETOBJ_RESET = 0x15 -+ NFT_MSG_MAX = 0x19 -+ NFTA_LIST_UNPEC = 0x0 -+ NFTA_LIST_ELEM = 0x1 -+ NFTA_HOOK_UNSPEC = 0x0 -+ NFTA_HOOK_HOOKNUM = 0x1 -+ NFTA_HOOK_PRIORITY = 0x2 -+ NFTA_HOOK_DEV = 0x3 -+ NFT_TABLE_F_DORMANT = 0x1 -+ NFTA_TABLE_UNSPEC = 0x0 -+ NFTA_TABLE_NAME = 0x1 -+ NFTA_TABLE_FLAGS = 0x2 -+ NFTA_TABLE_USE = 0x3 -+ NFTA_CHAIN_UNSPEC = 0x0 -+ NFTA_CHAIN_TABLE = 0x1 -+ NFTA_CHAIN_HANDLE = 0x2 -+ NFTA_CHAIN_NAME = 0x3 -+ NFTA_CHAIN_HOOK = 0x4 -+ NFTA_CHAIN_POLICY = 0x5 -+ NFTA_CHAIN_USE = 0x6 -+ NFTA_CHAIN_TYPE = 0x7 -+ NFTA_CHAIN_COUNTERS = 0x8 -+ NFTA_CHAIN_PAD = 0x9 -+ NFTA_RULE_UNSPEC = 0x0 -+ NFTA_RULE_TABLE = 0x1 -+ NFTA_RULE_CHAIN = 0x2 -+ NFTA_RULE_HANDLE = 0x3 -+ NFTA_RULE_EXPRESSIONS = 0x4 -+ NFTA_RULE_COMPAT = 0x5 -+ NFTA_RULE_POSITION = 0x6 -+ NFTA_RULE_USERDATA = 0x7 -+ NFTA_RULE_PAD = 0x8 -+ NFTA_RULE_ID = 0x9 -+ NFT_RULE_COMPAT_F_INV = 0x2 -+ NFT_RULE_COMPAT_F_MASK = 0x2 -+ NFTA_RULE_COMPAT_UNSPEC = 0x0 -+ NFTA_RULE_COMPAT_PROTO = 0x1 -+ NFTA_RULE_COMPAT_FLAGS = 0x2 -+ NFT_SET_ANONYMOUS = 0x1 -+ NFT_SET_CONSTANT = 0x2 -+ NFT_SET_INTERVAL = 0x4 -+ NFT_SET_MAP = 0x8 -+ NFT_SET_TIMEOUT = 0x10 -+ NFT_SET_EVAL = 0x20 -+ NFT_SET_OBJECT = 0x40 -+ NFT_SET_POL_PERFORMANCE = 0x0 -+ NFT_SET_POL_MEMORY = 0x1 -+ NFTA_SET_DESC_UNSPEC = 0x0 -+ NFTA_SET_DESC_SIZE = 0x1 -+ NFTA_SET_UNSPEC = 0x0 -+ NFTA_SET_TABLE = 0x1 -+ NFTA_SET_NAME = 0x2 -+ NFTA_SET_FLAGS = 0x3 -+ NFTA_SET_KEY_TYPE = 0x4 -+ NFTA_SET_KEY_LEN = 0x5 -+ NFTA_SET_DATA_TYPE = 0x6 -+ NFTA_SET_DATA_LEN = 0x7 -+ NFTA_SET_POLICY = 0x8 -+ NFTA_SET_DESC = 0x9 -+ NFTA_SET_ID = 0xa -+ NFTA_SET_TIMEOUT = 0xb -+ NFTA_SET_GC_INTERVAL = 0xc -+ NFTA_SET_USERDATA = 0xd -+ NFTA_SET_PAD = 0xe -+ NFTA_SET_OBJ_TYPE = 0xf -+ NFT_SET_ELEM_INTERVAL_END = 0x1 -+ NFTA_SET_ELEM_UNSPEC = 0x0 -+ NFTA_SET_ELEM_KEY = 0x1 -+ NFTA_SET_ELEM_DATA = 0x2 -+ NFTA_SET_ELEM_FLAGS = 0x3 -+ NFTA_SET_ELEM_TIMEOUT = 0x4 -+ NFTA_SET_ELEM_EXPIRATION = 0x5 -+ NFTA_SET_ELEM_USERDATA = 0x6 -+ NFTA_SET_ELEM_EXPR = 0x7 -+ NFTA_SET_ELEM_PAD = 0x8 -+ NFTA_SET_ELEM_OBJREF = 0x9 -+ NFTA_SET_ELEM_LIST_UNSPEC = 0x0 -+ NFTA_SET_ELEM_LIST_TABLE = 0x1 -+ NFTA_SET_ELEM_LIST_SET = 0x2 -+ NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 -+ NFTA_SET_ELEM_LIST_SET_ID = 0x4 -+ NFT_DATA_VALUE = 0x0 -+ NFT_DATA_VERDICT = 0xffffff00 -+ NFTA_DATA_UNSPEC = 0x0 -+ NFTA_DATA_VALUE = 0x1 -+ NFTA_DATA_VERDICT = 0x2 -+ NFTA_VERDICT_UNSPEC = 0x0 -+ NFTA_VERDICT_CODE = 0x1 -+ NFTA_VERDICT_CHAIN = 0x2 -+ NFTA_EXPR_UNSPEC = 0x0 -+ NFTA_EXPR_NAME = 0x1 -+ NFTA_EXPR_DATA = 0x2 -+ NFTA_IMMEDIATE_UNSPEC = 0x0 -+ NFTA_IMMEDIATE_DREG = 0x1 -+ NFTA_IMMEDIATE_DATA = 0x2 -+ NFTA_BITWISE_UNSPEC = 0x0 -+ NFTA_BITWISE_SREG = 0x1 -+ NFTA_BITWISE_DREG = 0x2 -+ NFTA_BITWISE_LEN = 0x3 -+ NFTA_BITWISE_MASK = 0x4 -+ NFTA_BITWISE_XOR = 0x5 -+ NFT_BYTEORDER_NTOH = 0x0 -+ NFT_BYTEORDER_HTON = 0x1 -+ NFTA_BYTEORDER_UNSPEC = 0x0 -+ NFTA_BYTEORDER_SREG = 0x1 -+ NFTA_BYTEORDER_DREG = 0x2 -+ NFTA_BYTEORDER_OP = 0x3 -+ NFTA_BYTEORDER_LEN = 0x4 -+ NFTA_BYTEORDER_SIZE = 0x5 -+ NFT_CMP_EQ = 0x0 -+ NFT_CMP_NEQ = 0x1 -+ NFT_CMP_LT = 0x2 -+ NFT_CMP_LTE = 0x3 -+ NFT_CMP_GT = 0x4 -+ NFT_CMP_GTE = 0x5 -+ NFTA_CMP_UNSPEC = 0x0 -+ NFTA_CMP_SREG = 0x1 -+ NFTA_CMP_OP = 0x2 -+ NFTA_CMP_DATA = 0x3 -+ NFT_RANGE_EQ = 0x0 -+ NFT_RANGE_NEQ = 0x1 -+ NFTA_RANGE_UNSPEC = 0x0 -+ NFTA_RANGE_SREG = 0x1 -+ NFTA_RANGE_OP = 0x2 -+ NFTA_RANGE_FROM_DATA = 0x3 -+ NFTA_RANGE_TO_DATA = 0x4 -+ NFT_LOOKUP_F_INV = 0x1 -+ NFTA_LOOKUP_UNSPEC = 0x0 -+ NFTA_LOOKUP_SET = 0x1 -+ NFTA_LOOKUP_SREG = 0x2 -+ NFTA_LOOKUP_DREG = 0x3 -+ NFTA_LOOKUP_SET_ID = 0x4 -+ NFTA_LOOKUP_FLAGS = 0x5 -+ NFT_DYNSET_OP_ADD = 0x0 -+ NFT_DYNSET_OP_UPDATE = 0x1 -+ NFT_DYNSET_F_INV = 0x1 -+ NFTA_DYNSET_UNSPEC = 0x0 -+ NFTA_DYNSET_SET_NAME = 0x1 -+ NFTA_DYNSET_SET_ID = 0x2 -+ NFTA_DYNSET_OP = 0x3 -+ NFTA_DYNSET_SREG_KEY = 0x4 -+ NFTA_DYNSET_SREG_DATA = 0x5 -+ NFTA_DYNSET_TIMEOUT = 0x6 -+ NFTA_DYNSET_EXPR = 0x7 -+ NFTA_DYNSET_PAD = 0x8 -+ NFTA_DYNSET_FLAGS = 0x9 -+ NFT_PAYLOAD_LL_HEADER = 0x0 -+ NFT_PAYLOAD_NETWORK_HEADER = 0x1 -+ NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 -+ NFT_PAYLOAD_CSUM_NONE = 0x0 -+ NFT_PAYLOAD_CSUM_INET = 0x1 -+ NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 -+ NFTA_PAYLOAD_UNSPEC = 0x0 -+ NFTA_PAYLOAD_DREG = 0x1 -+ NFTA_PAYLOAD_BASE = 0x2 -+ NFTA_PAYLOAD_OFFSET = 0x3 -+ NFTA_PAYLOAD_LEN = 0x4 -+ NFTA_PAYLOAD_SREG = 0x5 -+ NFTA_PAYLOAD_CSUM_TYPE = 0x6 -+ NFTA_PAYLOAD_CSUM_OFFSET = 0x7 -+ NFTA_PAYLOAD_CSUM_FLAGS = 0x8 -+ NFT_EXTHDR_F_PRESENT = 0x1 -+ NFT_EXTHDR_OP_IPV6 = 0x0 -+ NFT_EXTHDR_OP_TCPOPT = 0x1 -+ NFTA_EXTHDR_UNSPEC = 0x0 -+ NFTA_EXTHDR_DREG = 0x1 -+ NFTA_EXTHDR_TYPE = 0x2 -+ NFTA_EXTHDR_OFFSET = 0x3 -+ NFTA_EXTHDR_LEN = 0x4 -+ NFTA_EXTHDR_FLAGS = 0x5 -+ NFTA_EXTHDR_OP = 0x6 -+ NFTA_EXTHDR_SREG = 0x7 -+ NFT_META_LEN = 0x0 -+ NFT_META_PROTOCOL = 0x1 -+ NFT_META_PRIORITY = 0x2 -+ NFT_META_MARK = 0x3 -+ NFT_META_IIF = 0x4 -+ NFT_META_OIF = 0x5 -+ NFT_META_IIFNAME = 0x6 -+ NFT_META_OIFNAME = 0x7 -+ NFT_META_IIFTYPE = 0x8 -+ NFT_META_OIFTYPE = 0x9 -+ NFT_META_SKUID = 0xa -+ NFT_META_SKGID = 0xb -+ NFT_META_NFTRACE = 0xc -+ NFT_META_RTCLASSID = 0xd -+ NFT_META_SECMARK = 0xe -+ NFT_META_NFPROTO = 0xf -+ NFT_META_L4PROTO = 0x10 -+ NFT_META_BRI_IIFNAME = 0x11 -+ NFT_META_BRI_OIFNAME = 0x12 -+ NFT_META_PKTTYPE = 0x13 -+ NFT_META_CPU = 0x14 -+ NFT_META_IIFGROUP = 0x15 -+ NFT_META_OIFGROUP = 0x16 -+ NFT_META_CGROUP = 0x17 -+ NFT_META_PRANDOM = 0x18 -+ NFT_RT_CLASSID = 0x0 -+ NFT_RT_NEXTHOP4 = 0x1 -+ NFT_RT_NEXTHOP6 = 0x2 -+ NFT_RT_TCPMSS = 0x3 -+ NFT_HASH_JENKINS = 0x0 -+ NFT_HASH_SYM = 0x1 -+ NFTA_HASH_UNSPEC = 0x0 -+ NFTA_HASH_SREG = 0x1 -+ NFTA_HASH_DREG = 0x2 -+ NFTA_HASH_LEN = 0x3 -+ NFTA_HASH_MODULUS = 0x4 -+ NFTA_HASH_SEED = 0x5 -+ NFTA_HASH_OFFSET = 0x6 -+ NFTA_HASH_TYPE = 0x7 -+ NFTA_META_UNSPEC = 0x0 -+ NFTA_META_DREG = 0x1 -+ NFTA_META_KEY = 0x2 -+ NFTA_META_SREG = 0x3 -+ NFTA_RT_UNSPEC = 0x0 -+ NFTA_RT_DREG = 0x1 -+ NFTA_RT_KEY = 0x2 -+ NFT_CT_STATE = 0x0 -+ NFT_CT_DIRECTION = 0x1 -+ NFT_CT_STATUS = 0x2 -+ NFT_CT_MARK = 0x3 -+ NFT_CT_SECMARK = 0x4 -+ NFT_CT_EXPIRATION = 0x5 -+ NFT_CT_HELPER = 0x6 -+ NFT_CT_L3PROTOCOL = 0x7 -+ NFT_CT_SRC = 0x8 -+ NFT_CT_DST = 0x9 -+ NFT_CT_PROTOCOL = 0xa -+ NFT_CT_PROTO_SRC = 0xb -+ NFT_CT_PROTO_DST = 0xc -+ NFT_CT_LABELS = 0xd -+ NFT_CT_PKTS = 0xe -+ NFT_CT_BYTES = 0xf -+ NFT_CT_AVGPKT = 0x10 -+ NFT_CT_ZONE = 0x11 -+ NFT_CT_EVENTMASK = 0x12 -+ NFTA_CT_UNSPEC = 0x0 -+ NFTA_CT_DREG = 0x1 -+ NFTA_CT_KEY = 0x2 -+ NFTA_CT_DIRECTION = 0x3 -+ NFTA_CT_SREG = 0x4 -+ NFT_LIMIT_PKTS = 0x0 -+ NFT_LIMIT_PKT_BYTES = 0x1 -+ NFT_LIMIT_F_INV = 0x1 -+ NFTA_LIMIT_UNSPEC = 0x0 -+ NFTA_LIMIT_RATE = 0x1 -+ NFTA_LIMIT_UNIT = 0x2 -+ NFTA_LIMIT_BURST = 0x3 -+ NFTA_LIMIT_TYPE = 0x4 -+ NFTA_LIMIT_FLAGS = 0x5 -+ NFTA_LIMIT_PAD = 0x6 -+ NFTA_COUNTER_UNSPEC = 0x0 -+ NFTA_COUNTER_BYTES = 0x1 -+ NFTA_COUNTER_PACKETS = 0x2 -+ NFTA_COUNTER_PAD = 0x3 -+ NFTA_LOG_UNSPEC = 0x0 -+ NFTA_LOG_GROUP = 0x1 -+ NFTA_LOG_PREFIX = 0x2 -+ NFTA_LOG_SNAPLEN = 0x3 -+ NFTA_LOG_QTHRESHOLD = 0x4 -+ NFTA_LOG_LEVEL = 0x5 -+ NFTA_LOG_FLAGS = 0x6 -+ NFTA_QUEUE_UNSPEC = 0x0 -+ NFTA_QUEUE_NUM = 0x1 -+ NFTA_QUEUE_TOTAL = 0x2 -+ NFTA_QUEUE_FLAGS = 0x3 -+ NFTA_QUEUE_SREG_QNUM = 0x4 -+ NFT_QUOTA_F_INV = 0x1 -+ NFT_QUOTA_F_DEPLETED = 0x2 -+ NFTA_QUOTA_UNSPEC = 0x0 -+ NFTA_QUOTA_BYTES = 0x1 -+ NFTA_QUOTA_FLAGS = 0x2 -+ NFTA_QUOTA_PAD = 0x3 -+ NFTA_QUOTA_CONSUMED = 0x4 -+ NFT_REJECT_ICMP_UNREACH = 0x0 -+ NFT_REJECT_TCP_RST = 0x1 -+ NFT_REJECT_ICMPX_UNREACH = 0x2 -+ NFT_REJECT_ICMPX_NO_ROUTE = 0x0 -+ NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 -+ NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 -+ NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 -+ NFTA_REJECT_UNSPEC = 0x0 -+ NFTA_REJECT_TYPE = 0x1 -+ NFTA_REJECT_ICMP_CODE = 0x2 -+ NFT_NAT_SNAT = 0x0 -+ NFT_NAT_DNAT = 0x1 -+ NFTA_NAT_UNSPEC = 0x0 -+ NFTA_NAT_TYPE = 0x1 -+ NFTA_NAT_FAMILY = 0x2 -+ NFTA_NAT_REG_ADDR_MIN = 0x3 -+ NFTA_NAT_REG_ADDR_MAX = 0x4 -+ NFTA_NAT_REG_PROTO_MIN = 0x5 -+ NFTA_NAT_REG_PROTO_MAX = 0x6 -+ NFTA_NAT_FLAGS = 0x7 -+ NFTA_MASQ_UNSPEC = 0x0 -+ NFTA_MASQ_FLAGS = 0x1 -+ NFTA_MASQ_REG_PROTO_MIN = 0x2 -+ NFTA_MASQ_REG_PROTO_MAX = 0x3 -+ NFTA_REDIR_UNSPEC = 0x0 -+ NFTA_REDIR_REG_PROTO_MIN = 0x1 -+ NFTA_REDIR_REG_PROTO_MAX = 0x2 -+ NFTA_REDIR_FLAGS = 0x3 -+ NFTA_DUP_UNSPEC = 0x0 -+ NFTA_DUP_SREG_ADDR = 0x1 -+ NFTA_DUP_SREG_DEV = 0x2 -+ NFTA_FWD_UNSPEC = 0x0 -+ NFTA_FWD_SREG_DEV = 0x1 -+ NFTA_OBJREF_UNSPEC = 0x0 -+ NFTA_OBJREF_IMM_TYPE = 0x1 -+ NFTA_OBJREF_IMM_NAME = 0x2 -+ NFTA_OBJREF_SET_SREG = 0x3 -+ NFTA_OBJREF_SET_NAME = 0x4 -+ NFTA_OBJREF_SET_ID = 0x5 -+ NFTA_GEN_UNSPEC = 0x0 -+ NFTA_GEN_ID = 0x1 -+ NFTA_GEN_PROC_PID = 0x2 -+ NFTA_GEN_PROC_NAME = 0x3 -+ NFTA_FIB_UNSPEC = 0x0 -+ NFTA_FIB_DREG = 0x1 -+ NFTA_FIB_RESULT = 0x2 -+ NFTA_FIB_FLAGS = 0x3 -+ NFT_FIB_RESULT_UNSPEC = 0x0 -+ NFT_FIB_RESULT_OIF = 0x1 -+ NFT_FIB_RESULT_OIFNAME = 0x2 -+ NFT_FIB_RESULT_ADDRTYPE = 0x3 -+ NFTA_FIB_F_SADDR = 0x1 -+ NFTA_FIB_F_DADDR = 0x2 -+ NFTA_FIB_F_MARK = 0x4 -+ NFTA_FIB_F_IIF = 0x8 -+ NFTA_FIB_F_OIF = 0x10 -+ NFTA_FIB_F_PRESENT = 0x20 -+ NFTA_CT_HELPER_UNSPEC = 0x0 -+ NFTA_CT_HELPER_NAME = 0x1 -+ NFTA_CT_HELPER_L3PROTO = 0x2 -+ NFTA_CT_HELPER_L4PROTO = 0x3 -+ NFTA_OBJ_UNSPEC = 0x0 -+ NFTA_OBJ_TABLE = 0x1 -+ NFTA_OBJ_NAME = 0x2 -+ NFTA_OBJ_TYPE = 0x3 -+ NFTA_OBJ_DATA = 0x4 -+ NFTA_OBJ_USE = 0x5 -+ NFTA_TRACE_UNSPEC = 0x0 -+ NFTA_TRACE_TABLE = 0x1 -+ NFTA_TRACE_CHAIN = 0x2 -+ NFTA_TRACE_RULE_HANDLE = 0x3 -+ NFTA_TRACE_TYPE = 0x4 -+ NFTA_TRACE_VERDICT = 0x5 -+ NFTA_TRACE_ID = 0x6 -+ NFTA_TRACE_LL_HEADER = 0x7 -+ NFTA_TRACE_NETWORK_HEADER = 0x8 -+ NFTA_TRACE_TRANSPORT_HEADER = 0x9 -+ NFTA_TRACE_IIF = 0xa -+ NFTA_TRACE_IIFTYPE = 0xb -+ NFTA_TRACE_OIF = 0xc -+ NFTA_TRACE_OIFTYPE = 0xd -+ NFTA_TRACE_MARK = 0xe -+ NFTA_TRACE_NFPROTO = 0xf -+ NFTA_TRACE_POLICY = 0x10 -+ NFTA_TRACE_PAD = 0x11 -+ NFT_TRACETYPE_UNSPEC = 0x0 -+ NFT_TRACETYPE_POLICY = 0x1 -+ NFT_TRACETYPE_RETURN = 0x2 -+ NFT_TRACETYPE_RULE = 0x3 -+ NFTA_NG_UNSPEC = 0x0 -+ NFTA_NG_DREG = 0x1 -+ NFTA_NG_MODULUS = 0x2 -+ NFTA_NG_TYPE = 0x3 -+ NFTA_NG_OFFSET = 0x4 -+ NFT_NG_INCREMENTAL = 0x0 -+ NFT_NG_RANDOM = 0x1 -+) -+ -+type RTCTime struct { -+ Sec int32 -+ Min int32 -+ Hour int32 -+ Mday int32 -+ Mon int32 -+ Year int32 -+ Wday int32 -+ Yday int32 -+ Isdst int32 -+} -+ -+type RTCWkAlrm struct { -+ Enabled uint8 -+ Pending uint8 -+ Time RTCTime -+} -+ -+type RTCPLLInfo struct { -+ Ctrl int32 -+ Value int32 -+ Max int32 -+ Min int32 -+ Posmult int32 -+ Negmult int32 -+ Clock int64 -+} -+ -+type BlkpgIoctlArg struct { -+ Op int32 -+ Flags int32 -+ Datalen int32 -+ Data *byte -+} -+ -+type BlkpgPartition struct { -+ Start int64 -+ Length int64 -+ Pno int32 -+ Devname [64]uint8 -+ Volname [64]uint8 -+ _ [4]byte -+} -+ -+const ( -+ BLKPG = 0x1269 -+ BLKPG_ADD_PARTITION = 0x1 -+ BLKPG_DEL_PARTITION = 0x2 -+ BLKPG_RESIZE_PARTITION = 0x3 -+) -+ -+const ( -+ NETNSA_NONE = 0x0 -+ NETNSA_NSID = 0x1 -+ NETNSA_PID = 0x2 -+ NETNSA_FD = 0x3 -+) -+ -+type XDPRingOffset struct { -+ Producer uint64 -+ Consumer uint64 -+ Desc uint64 -+} -+ -+type XDPMmapOffsets struct { -+ Rx XDPRingOffset -+ Tx XDPRingOffset -+ Fr XDPRingOffset -+ Cr XDPRingOffset -+} -+ -+type XDPUmemReg struct { -+ Addr uint64 -+ Len uint64 -+ Size uint32 -+ Headroom uint32 -+} -+ -+type XDPStatistics struct { -+ Rx_dropped uint64 -+ Rx_invalid_descs uint64 -+ Tx_invalid_descs uint64 -+} -+ -+type XDPDesc struct { -+ Addr uint64 -+ Len uint32 -+ Options uint32 -+} -+ -+const ( -+ NCSI_CMD_UNSPEC = 0x0 -+ NCSI_CMD_PKG_INFO = 0x1 -+ NCSI_CMD_SET_INTERFACE = 0x2 -+ NCSI_CMD_CLEAR_INTERFACE = 0x3 -+ NCSI_ATTR_UNSPEC = 0x0 -+ NCSI_ATTR_IFINDEX = 0x1 -+ NCSI_ATTR_PACKAGE_LIST = 0x2 -+ NCSI_ATTR_PACKAGE_ID = 0x3 -+ NCSI_ATTR_CHANNEL_ID = 0x4 -+ NCSI_PKG_ATTR_UNSPEC = 0x0 -+ NCSI_PKG_ATTR = 0x1 -+ NCSI_PKG_ATTR_ID = 0x2 -+ NCSI_PKG_ATTR_FORCED = 0x3 -+ NCSI_PKG_ATTR_CHANNEL_LIST = 0x4 -+ NCSI_CHANNEL_ATTR_UNSPEC = 0x0 -+ NCSI_CHANNEL_ATTR = 0x1 -+ NCSI_CHANNEL_ATTR_ID = 0x2 -+ NCSI_CHANNEL_ATTR_VERSION_MAJOR = 0x3 -+ NCSI_CHANNEL_ATTR_VERSION_MINOR = 0x4 -+ NCSI_CHANNEL_ATTR_VERSION_STR = 0x5 -+ NCSI_CHANNEL_ATTR_LINK_STATE = 0x6 -+ NCSI_CHANNEL_ATTR_ACTIVE = 0x7 -+ NCSI_CHANNEL_ATTR_FORCED = 0x8 -+ NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9 -+ NCSI_CHANNEL_ATTR_VLAN_ID = 0xa -+) -+ -+type ScmTimestamping struct { -+ Ts [3]Timespec -+} -+ -+const ( -+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1 -+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 -+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4 -+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8 -+ SOF_TIMESTAMPING_SOFTWARE = 0x10 -+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20 -+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40 -+ SOF_TIMESTAMPING_OPT_ID = 0x80 -+ SOF_TIMESTAMPING_TX_SCHED = 0x100 -+ SOF_TIMESTAMPING_TX_ACK = 0x200 -+ SOF_TIMESTAMPING_OPT_CMSG = 0x400 -+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800 -+ SOF_TIMESTAMPING_OPT_STATS = 0x1000 -+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000 -+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000 -+ -+ SOF_TIMESTAMPING_LAST = 0x4000 -+ SOF_TIMESTAMPING_MASK = 0x7fff -+ -+ SCM_TSTAMP_SND = 0x0 -+ SCM_TSTAMP_SCHED = 0x1 -+ SCM_TSTAMP_ACK = 0x2 -+) -+ -+type SockExtendedErr struct { -+ Errno uint32 -+ Origin uint8 -+ Type uint8 -+ Code uint8 -+ Pad uint8 -+ Info uint32 -+ Data uint32 -+} --- -2.23.0 - diff --git a/patch/0176-docker-kill-container-process-if-its-status-is-not-r.patch b/patch/0176-docker-kill-container-process-if-its-status-is-not-r.patch deleted file mode 100644 index 49693f2..0000000 --- a/patch/0176-docker-kill-container-process-if-its-status-is-not-r.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 544d24895836ec576febaf94be8affde56449fba Mon Sep 17 00:00:00 2001 -From: xiadanni1 -Date: Fri, 27 Nov 2020 16:31:56 +0800 -Subject: [PATCH] docker: kill container process if its status is not running - when start daemon - -Signed-off-by: xiadanni1 ---- - components/engine/daemon/daemon.go | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 3ff5691..3cc2a20 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -17,8 +17,10 @@ import ( - "runtime" - "strings" - "sync" -+ "syscall" - "time" - -+ "golang.org/x/sys/unix" - "google.golang.org/grpc" - - "github.com/containerd/containerd" -@@ -43,6 +45,7 @@ import ( - "github.com/moby/buildkit/util/resolver" - "github.com/moby/buildkit/util/tracing" - "github.com/sirupsen/logrus" -+ - // register graph drivers - _ "github.com/docker/docker/daemon/graphdriver/register" - "github.com/docker/docker/daemon/stats" -@@ -51,7 +54,7 @@ import ( - "github.com/docker/docker/image" - "github.com/docker/docker/layer" - "github.com/docker/docker/libcontainerd" -- "github.com/docker/docker/migrate/v1" -+ v1 "github.com/docker/docker/migrate/v1" - "github.com/docker/docker/pkg/idtools" - "github.com/docker/docker/pkg/locker" - "github.com/docker/docker/pkg/plugingetter" -@@ -389,6 +392,15 @@ func (daemon *Daemon) restore() error { - } - } - -+ if alive && !c.IsRunning() && pid > 1 { -+ if c.Pid == 0 { -+ c.Pid = pid -+ } -+ err := unix.Kill(pid, syscall.SIGKILL) -+ logrus.Warnf("process %v is killed as container=%s is alive but not running, err: %v", pid, c.ID, err) -+ return -+ } -+ - if c.IsRunning() || c.IsPaused() { - c.RestartManager().Cancel() // manually start containers because some need to wait for swarm networking - --- -1.8.3.1 - diff --git a/patch/0177-docker-components-cli-vendor-add-new-config-file-for-riscv.patch b/patch/0177-docker-components-cli-vendor-add-new-config-file-for-riscv.patch deleted file mode 100644 index 7ecb64c..0000000 --- a/patch/0177-docker-components-cli-vendor-add-new-config-file-for-riscv.patch +++ /dev/null @@ -1,7730 +0,0 @@ -From 068924006c5de100f3dc382eef561e6d307b28fd Mon Sep 17 00:00:00 2001 -From: yangyanchao -Date: Sat, 19 Dec 2020 09:25:01 +0000 -Subject: [PATCH 3/3] docker:components:cli:vendor:add new config files for - riscv64 - -Signiei-off-by: yangyanchao ---- - .../continuity/sysx/xattr_linux_riscv64.go | 111 + - .../golang.org/x/sys/unix/asm_linux_riscv64.s | 47 + - .../x/sys/unix/syscall_linux_riscv64.go | 213 ++ - .../x/sys/unix/zerrors_linux_riscv64.go | 2769 +++++++++++++++++ - .../x/sys/unix/zsyscall_linux_riscv64.go | 2188 +++++++++++++ - .../x/sys/unix/zsysnum_linux_riscv64.go | 287 ++ - .../x/sys/unix/ztypes_linux_riscv64.go | 2046 ++++++++++++ - 7 files changed, 7661 insertions(+) - create mode 100644 components/cli/vendor/github.com/containerd/continuity/sysx/xattr_linux_riscv64.go - create mode 100644 components/cli/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s - create mode 100644 components/cli/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go - create mode 100644 components/cli/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go - create mode 100644 components/cli/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go - create mode 100644 components/cli/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go - create mode 100644 components/cli/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go - -diff --git a/components/cli/vendor/github.com/containerd/continuity/sysx/xattr_linux_riscv64.go b/components/cli/vendor/github.com/containerd/continuity/sysx/xattr_linux_riscv64.go -new file mode 100644 -index 0000000..dec46fa ---- /dev/null -+++ b/components/cli/vendor/github.com/containerd/continuity/sysx/xattr_linux_riscv64.go -@@ -0,0 +1,111 @@ -+// mksyscall.pl xattr_linux.go -+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT -+ -+package sysx -+ -+import ( -+ "syscall" -+ "unsafe" -+) -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func llistxattr(path string, dest []byte) (sz int, err error) { -+ var _p0 *byte -+ _p0, err = syscall.BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 unsafe.Pointer -+ if len(dest) > 0 { -+ _p1 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p1 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := syscall.Syscall(syscall.SYS_LLISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest))) -+ use(unsafe.Pointer(_p0)) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func lremovexattr(path string, attr string) (err error) { -+ var _p0 *byte -+ _p0, err = syscall.BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = syscall.BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ _, _, e1 := syscall.Syscall(syscall.SYS_LREMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) -+ use(unsafe.Pointer(_p0)) -+ use(unsafe.Pointer(_p1)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func lsetxattr(path string, attr string, data []byte, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = syscall.BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = syscall.BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p2 unsafe.Pointer -+ if len(data) > 0 { -+ _p2 = unsafe.Pointer(&data[0]) -+ } else { -+ _p2 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0) -+ use(unsafe.Pointer(_p0)) -+ use(unsafe.Pointer(_p1)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func lgetxattr(path string, attr string, dest []byte) (sz int, err error) { -+ var _p0 *byte -+ _p0, err = syscall.BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = syscall.BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p2 unsafe.Pointer -+ if len(dest) > 0 { -+ _p2 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p2 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0) -+ use(unsafe.Pointer(_p0)) -+ use(unsafe.Pointer(_p1)) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -diff --git a/components/cli/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s b/components/cli/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s -new file mode 100644 -index 0000000..3cfefed ---- /dev/null -+++ b/components/cli/vendor/golang.org/x/sys/unix/asm_linux_riscv64.s -@@ -0,0 +1,47 @@ -+// Copyright 2019 The Go Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style -+// license that can be found in the LICENSE file. -+ -+// +build riscv64,!gccgo -+ -+#include "textflag.h" -+ -+// -+// System calls for linux/riscv64. -+// -+// Where available, just jump to package syscall's implementation of -+// these functions. -+ -+TEXT ·Syscall(SB),NOSPLIT,$0-56 -+ JMP syscall·Syscall(SB) -+ -+TEXT ·Syscall6(SB),NOSPLIT,$0-80 -+ JMP syscall·Syscall6(SB) -+ -+TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 -+ CALL runtime·entersyscall(SB) -+ MOV a1+8(FP), A0 -+ MOV a2+16(FP), A1 -+ MOV a3+24(FP), A2 -+ MOV trap+0(FP), A7 // syscall entry -+ ECALL -+ MOV A0, r1+32(FP) // r1 -+ MOV A1, r2+40(FP) // r2 -+ CALL runtime·exitsyscall(SB) -+ RET -+ -+TEXT ·RawSyscall(SB),NOSPLIT,$0-56 -+ JMP syscall·RawSyscall(SB) -+ -+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 -+ JMP syscall·RawSyscall6(SB) -+ -+TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48 -+ MOV a1+8(FP), A0 -+ MOV a2+16(FP), A1 -+ MOV a3+24(FP), A2 -+ MOV trap+0(FP), A7 // syscall entry -+ ECALL -+ MOV A0, r1+32(FP) -+ MOV A1, r2+40(FP) -+ RET -diff --git a/components/cli/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/components/cli/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go -new file mode 100644 -index 0000000..f23ca45 ---- /dev/null -+++ b/components/cli/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go -@@ -0,0 +1,213 @@ -+// Copyright 2018 The Go Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style -+// license that can be found in the LICENSE file. -+ -+// +build riscv64,linux -+ -+package unix -+ -+import "unsafe" -+ -+func EpollCreate(size int) (fd int, err error) { -+ if size <= 0 { -+ return -1, EINVAL -+ } -+ return EpollCreate1(0) -+} -+ -+//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT -+//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 -+//sys Fchown(fd int, uid int, gid int) (err error) -+//sys Fstat(fd int, stat *Stat_t) (err error) -+//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) -+//sys Fstatfs(fd int, buf *Statfs_t) (err error) -+//sys Ftruncate(fd int, length int64) (err error) -+//sysnb Getegid() (egid int) -+//sysnb Geteuid() (euid int) -+//sysnb Getgid() (gid int) -+//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) -+//sysnb Getuid() (uid int) -+//sys Listen(s int, n int) (err error) -+//sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 -+//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 -+//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK -+ -+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { -+ var ts *Timespec -+ if timeout != nil { -+ ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} -+ } -+ return Pselect(nfd, r, w, e, ts, nil) -+} -+ -+//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) -+//sys Setfsgid(gid int) (err error) -+//sys Setfsuid(uid int) (err error) -+//sysnb Setregid(rgid int, egid int) (err error) -+//sysnb Setresgid(rgid int, egid int, sgid int) (err error) -+//sysnb Setresuid(ruid int, euid int, suid int) (err error) -+//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) -+//sysnb Setreuid(ruid int, euid int) (err error) -+//sys Shutdown(fd int, how int) (err error) -+//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) -+ -+func Stat(path string, stat *Stat_t) (err error) { -+ return Fstatat(AT_FDCWD, path, stat, 0) -+} -+ -+func Lchown(path string, uid int, gid int) (err error) { -+ return Fchownat(AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW) -+} -+ -+func Lstat(path string, stat *Stat_t) (err error) { -+ return Fstatat(AT_FDCWD, path, stat, AT_SYMLINK_NOFOLLOW) -+} -+ -+//sys Statfs(path string, buf *Statfs_t) (err error) -+//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) -+//sys Truncate(path string, length int64) (err error) -+ -+func Ustat(dev int, ubuf *Ustat_t) (err error) { -+ return ENOSYS -+} -+ -+//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) -+//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) -+//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) -+//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) -+//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) -+//sysnb setgroups(n int, list *_Gid_t) (err error) -+//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) -+//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) -+//sysnb socket(domain int, typ int, proto int) (fd int, err error) -+//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) -+//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) -+//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) -+//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) -+//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) -+//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) -+//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) -+//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) -+ -+//sysnb Gettimeofday(tv *Timeval) (err error) -+ -+func setTimespec(sec, nsec int64) Timespec { -+ return Timespec{Sec: sec, Nsec: nsec} -+} -+ -+func setTimeval(sec, usec int64) Timeval { -+ return Timeval{Sec: sec, Usec: usec} -+} -+ -+func futimesat(dirfd int, path string, tv *[2]Timeval) (err error) { -+ if tv == nil { -+ return utimensat(dirfd, path, nil, 0) -+ } -+ -+ ts := []Timespec{ -+ NsecToTimespec(TimevalToNsec(tv[0])), -+ NsecToTimespec(TimevalToNsec(tv[1])), -+ } -+ return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) -+} -+ -+func Time(t *Time_t) (Time_t, error) { -+ var tv Timeval -+ err := Gettimeofday(&tv) -+ if err != nil { -+ return 0, err -+ } -+ if t != nil { -+ *t = Time_t(tv.Sec) -+ } -+ return Time_t(tv.Sec), nil -+} -+ -+func Utime(path string, buf *Utimbuf) error { -+ tv := []Timeval{ -+ {Sec: buf.Actime}, -+ {Sec: buf.Modtime}, -+ } -+ return Utimes(path, tv) -+} -+ -+func utimes(path string, tv *[2]Timeval) (err error) { -+ if tv == nil { -+ return utimensat(AT_FDCWD, path, nil, 0) -+ } -+ -+ ts := []Timespec{ -+ NsecToTimespec(TimevalToNsec(tv[0])), -+ NsecToTimespec(TimevalToNsec(tv[1])), -+ } -+ return utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) -+} -+ -+func Pipe(p []int) (err error) { -+ if len(p) != 2 { -+ return EINVAL -+ } -+ var pp [2]_C_int -+ err = pipe2(&pp, 0) -+ p[0] = int(pp[0]) -+ p[1] = int(pp[1]) -+ return -+} -+ -+//sysnb pipe2(p *[2]_C_int, flags int) (err error) -+ -+func Pipe2(p []int, flags int) (err error) { -+ if len(p) != 2 { -+ return EINVAL -+ } -+ var pp [2]_C_int -+ err = pipe2(&pp, flags) -+ p[0] = int(pp[0]) -+ p[1] = int(pp[1]) -+ return -+} -+ -+func (r *PtraceRegs) PC() uint64 { return r.Pc } -+ -+func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc } -+ -+func (iov *Iovec) SetLen(length int) { -+ iov.Len = uint64(length) -+} -+ -+func (msghdr *Msghdr) SetControllen(length int) { -+ msghdr.Controllen = uint64(length) -+} -+ -+func (cmsg *Cmsghdr) SetLen(length int) { -+ cmsg.Len = uint64(length) -+} -+ -+func InotifyInit() (fd int, err error) { -+ return InotifyInit1(0) -+} -+ -+func Dup2(oldfd int, newfd int) (err error) { -+ return Dup3(oldfd, newfd, 0) -+} -+ -+func Pause() error { -+ _, err := ppoll(nil, 0, nil, nil) -+ return err -+} -+ -+func Poll(fds []PollFd, timeout int) (n int, err error) { -+ var ts *Timespec -+ if timeout >= 0 { -+ ts = new(Timespec) -+ *ts = NsecToTimespec(int64(timeout) * 1e6) -+ } -+ if len(fds) == 0 { -+ return ppoll(nil, 0, ts, nil) -+ } -+ return ppoll(&fds[0], len(fds), ts, nil) -+} -+ -+func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { -+ return Renameat2(olddirfd, oldpath, newdirfd, newpath, 0) -+} -diff --git a/components/cli/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/components/cli/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go -new file mode 100644 -index 0000000..5aea4b9 ---- /dev/null -+++ b/components/cli/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go -@@ -0,0 +1,2769 @@ -+// mkerrors.sh -Wall -Werror -static -I/tmp/include -+// Code generated by the command above; see README.md. DO NOT EDIT. -+ -+// +build riscv64,linux -+ -+// Code generated by cmd/cgo -godefs; DO NOT EDIT. -+// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go -+ -+package unix -+ -+import "syscall" -+ -+const ( -+ AAFS_MAGIC = 0x5a3c69f0 -+ ADFS_SUPER_MAGIC = 0xadf5 -+ AFFS_SUPER_MAGIC = 0xadff -+ AFS_FS_MAGIC = 0x6b414653 -+ AFS_SUPER_MAGIC = 0x5346414f -+ AF_ALG = 0x26 -+ AF_APPLETALK = 0x5 -+ AF_ASH = 0x12 -+ AF_ATMPVC = 0x8 -+ AF_ATMSVC = 0x14 -+ AF_AX25 = 0x3 -+ AF_BLUETOOTH = 0x1f -+ AF_BRIDGE = 0x7 -+ AF_CAIF = 0x25 -+ AF_CAN = 0x1d -+ AF_DECnet = 0xc -+ AF_ECONET = 0x13 -+ AF_FILE = 0x1 -+ AF_IB = 0x1b -+ AF_IEEE802154 = 0x24 -+ AF_INET = 0x2 -+ AF_INET6 = 0xa -+ AF_IPX = 0x4 -+ AF_IRDA = 0x17 -+ AF_ISDN = 0x22 -+ AF_IUCV = 0x20 -+ AF_KCM = 0x29 -+ AF_KEY = 0xf -+ AF_LLC = 0x1a -+ AF_LOCAL = 0x1 -+ AF_MAX = 0x2d -+ AF_MPLS = 0x1c -+ AF_NETBEUI = 0xd -+ AF_NETLINK = 0x10 -+ AF_NETROM = 0x6 -+ AF_NFC = 0x27 -+ AF_PACKET = 0x11 -+ AF_PHONET = 0x23 -+ AF_PPPOX = 0x18 -+ AF_QIPCRTR = 0x2a -+ AF_RDS = 0x15 -+ AF_ROSE = 0xb -+ AF_ROUTE = 0x10 -+ AF_RXRPC = 0x21 -+ AF_SECURITY = 0xe -+ AF_SMC = 0x2b -+ AF_SNA = 0x16 -+ AF_TIPC = 0x1e -+ AF_UNIX = 0x1 -+ AF_UNSPEC = 0x0 -+ AF_VSOCK = 0x28 -+ AF_WANPIPE = 0x19 -+ AF_X25 = 0x9 -+ AF_XDP = 0x2c -+ ALG_OP_DECRYPT = 0x0 -+ ALG_OP_ENCRYPT = 0x1 -+ ALG_SET_AEAD_ASSOCLEN = 0x4 -+ ALG_SET_AEAD_AUTHSIZE = 0x5 -+ ALG_SET_IV = 0x2 -+ ALG_SET_KEY = 0x1 -+ ALG_SET_OP = 0x3 -+ ANON_INODE_FS_MAGIC = 0x9041934 -+ ARPHRD_6LOWPAN = 0x339 -+ ARPHRD_ADAPT = 0x108 -+ ARPHRD_APPLETLK = 0x8 -+ ARPHRD_ARCNET = 0x7 -+ ARPHRD_ASH = 0x30d -+ ARPHRD_ATM = 0x13 -+ ARPHRD_AX25 = 0x3 -+ ARPHRD_BIF = 0x307 -+ ARPHRD_CAIF = 0x336 -+ ARPHRD_CAN = 0x118 -+ ARPHRD_CHAOS = 0x5 -+ ARPHRD_CISCO = 0x201 -+ ARPHRD_CSLIP = 0x101 -+ ARPHRD_CSLIP6 = 0x103 -+ ARPHRD_DDCMP = 0x205 -+ ARPHRD_DLCI = 0xf -+ ARPHRD_ECONET = 0x30e -+ ARPHRD_EETHER = 0x2 -+ ARPHRD_ETHER = 0x1 -+ ARPHRD_EUI64 = 0x1b -+ ARPHRD_FCAL = 0x311 -+ ARPHRD_FCFABRIC = 0x313 -+ ARPHRD_FCPL = 0x312 -+ ARPHRD_FCPP = 0x310 -+ ARPHRD_FDDI = 0x306 -+ ARPHRD_FRAD = 0x302 -+ ARPHRD_HDLC = 0x201 -+ ARPHRD_HIPPI = 0x30c -+ ARPHRD_HWX25 = 0x110 -+ ARPHRD_IEEE1394 = 0x18 -+ ARPHRD_IEEE802 = 0x6 -+ ARPHRD_IEEE80211 = 0x321 -+ ARPHRD_IEEE80211_PRISM = 0x322 -+ ARPHRD_IEEE80211_RADIOTAP = 0x323 -+ ARPHRD_IEEE802154 = 0x324 -+ ARPHRD_IEEE802154_MONITOR = 0x325 -+ ARPHRD_IEEE802_TR = 0x320 -+ ARPHRD_INFINIBAND = 0x20 -+ ARPHRD_IP6GRE = 0x337 -+ ARPHRD_IPDDP = 0x309 -+ ARPHRD_IPGRE = 0x30a -+ ARPHRD_IRDA = 0x30f -+ ARPHRD_LAPB = 0x204 -+ ARPHRD_LOCALTLK = 0x305 -+ ARPHRD_LOOPBACK = 0x304 -+ ARPHRD_METRICOM = 0x17 -+ ARPHRD_NETLINK = 0x338 -+ ARPHRD_NETROM = 0x0 -+ ARPHRD_NONE = 0xfffe -+ ARPHRD_PHONET = 0x334 -+ ARPHRD_PHONET_PIPE = 0x335 -+ ARPHRD_PIMREG = 0x30b -+ ARPHRD_PPP = 0x200 -+ ARPHRD_PRONET = 0x4 -+ ARPHRD_RAWHDLC = 0x206 -+ ARPHRD_RAWIP = 0x207 -+ ARPHRD_ROSE = 0x10e -+ ARPHRD_RSRVD = 0x104 -+ ARPHRD_SIT = 0x308 -+ ARPHRD_SKIP = 0x303 -+ ARPHRD_SLIP = 0x100 -+ ARPHRD_SLIP6 = 0x102 -+ ARPHRD_TUNNEL = 0x300 -+ ARPHRD_TUNNEL6 = 0x301 -+ ARPHRD_VOID = 0xffff -+ ARPHRD_VSOCKMON = 0x33a -+ ARPHRD_X25 = 0x10f -+ AUTOFS_SUPER_MAGIC = 0x187 -+ B0 = 0x0 -+ B1000000 = 0x1008 -+ B110 = 0x3 -+ B115200 = 0x1002 -+ B1152000 = 0x1009 -+ B1200 = 0x9 -+ B134 = 0x4 -+ B150 = 0x5 -+ B1500000 = 0x100a -+ B1800 = 0xa -+ B19200 = 0xe -+ B200 = 0x6 -+ B2000000 = 0x100b -+ B230400 = 0x1003 -+ B2400 = 0xb -+ B2500000 = 0x100c -+ B300 = 0x7 -+ B3000000 = 0x100d -+ B3500000 = 0x100e -+ B38400 = 0xf -+ B4000000 = 0x100f -+ B460800 = 0x1004 -+ B4800 = 0xc -+ B50 = 0x1 -+ B500000 = 0x1005 -+ B57600 = 0x1001 -+ B576000 = 0x1006 -+ B600 = 0x8 -+ B75 = 0x2 -+ B921600 = 0x1007 -+ B9600 = 0xd -+ BALLOON_KVM_MAGIC = 0x13661366 -+ BDEVFS_MAGIC = 0x62646576 -+ BINFMTFS_MAGIC = 0x42494e4d -+ BLKBSZGET = 0x80081270 -+ BLKBSZSET = 0x40081271 -+ BLKFLSBUF = 0x1261 -+ BLKFRAGET = 0x1265 -+ BLKFRASET = 0x1264 -+ BLKGETSIZE = 0x1260 -+ BLKGETSIZE64 = 0x80081272 -+ BLKPBSZGET = 0x127b -+ BLKRAGET = 0x1263 -+ BLKRASET = 0x1262 -+ BLKROGET = 0x125e -+ BLKROSET = 0x125d -+ BLKRRPART = 0x125f -+ BLKSECTGET = 0x1267 -+ BLKSECTSET = 0x1266 -+ BLKSSZGET = 0x1268 -+ BOTHER = 0x1000 -+ BPF_A = 0x10 -+ BPF_ABS = 0x20 -+ BPF_ADD = 0x0 -+ BPF_ALU = 0x4 -+ BPF_AND = 0x50 -+ BPF_B = 0x10 -+ BPF_DIV = 0x30 -+ BPF_FS_MAGIC = 0xcafe4a11 -+ BPF_H = 0x8 -+ BPF_IMM = 0x0 -+ BPF_IND = 0x40 -+ BPF_JA = 0x0 -+ BPF_JEQ = 0x10 -+ BPF_JGE = 0x30 -+ BPF_JGT = 0x20 -+ BPF_JMP = 0x5 -+ BPF_JSET = 0x40 -+ BPF_K = 0x0 -+ BPF_LD = 0x0 -+ BPF_LDX = 0x1 -+ BPF_LEN = 0x80 -+ BPF_LL_OFF = -0x200000 -+ BPF_LSH = 0x60 -+ BPF_MAJOR_VERSION = 0x1 -+ BPF_MAXINSNS = 0x1000 -+ BPF_MEM = 0x60 -+ BPF_MEMWORDS = 0x10 -+ BPF_MINOR_VERSION = 0x1 -+ BPF_MISC = 0x7 -+ BPF_MOD = 0x90 -+ BPF_MSH = 0xa0 -+ BPF_MUL = 0x20 -+ BPF_NEG = 0x80 -+ BPF_NET_OFF = -0x100000 -+ BPF_OR = 0x40 -+ BPF_RET = 0x6 -+ BPF_RSH = 0x70 -+ BPF_ST = 0x2 -+ BPF_STX = 0x3 -+ BPF_SUB = 0x10 -+ BPF_TAX = 0x0 -+ BPF_TXA = 0x80 -+ BPF_W = 0x0 -+ BPF_X = 0x8 -+ BPF_XOR = 0xa0 -+ BRKINT = 0x2 -+ BS0 = 0x0 -+ BS1 = 0x2000 -+ BSDLY = 0x2000 -+ BTRFS_SUPER_MAGIC = 0x9123683e -+ BTRFS_TEST_MAGIC = 0x73727279 -+ CAN_BCM = 0x2 -+ CAN_EFF_FLAG = 0x80000000 -+ CAN_EFF_ID_BITS = 0x1d -+ CAN_EFF_MASK = 0x1fffffff -+ CAN_ERR_FLAG = 0x20000000 -+ CAN_ERR_MASK = 0x1fffffff -+ CAN_INV_FILTER = 0x20000000 -+ CAN_ISOTP = 0x6 -+ CAN_MAX_DLC = 0x8 -+ CAN_MAX_DLEN = 0x8 -+ CAN_MCNET = 0x5 -+ CAN_MTU = 0x10 -+ CAN_NPROTO = 0x7 -+ CAN_RAW = 0x1 -+ CAN_RAW_FILTER_MAX = 0x200 -+ CAN_RTR_FLAG = 0x40000000 -+ CAN_SFF_ID_BITS = 0xb -+ CAN_SFF_MASK = 0x7ff -+ CAN_TP16 = 0x3 -+ CAN_TP20 = 0x4 -+ CBAUD = 0x100f -+ CBAUDEX = 0x1000 -+ CFLUSH = 0xf -+ CGROUP2_SUPER_MAGIC = 0x63677270 -+ CGROUP_SUPER_MAGIC = 0x27e0eb -+ CIBAUD = 0x100f0000 -+ CLOCAL = 0x800 -+ CLOCK_BOOTTIME = 0x7 -+ CLOCK_BOOTTIME_ALARM = 0x9 -+ CLOCK_DEFAULT = 0x0 -+ CLOCK_EXT = 0x1 -+ CLOCK_INT = 0x2 -+ CLOCK_MONOTONIC = 0x1 -+ CLOCK_MONOTONIC_COARSE = 0x6 -+ CLOCK_MONOTONIC_RAW = 0x4 -+ CLOCK_PROCESS_CPUTIME_ID = 0x2 -+ CLOCK_REALTIME = 0x0 -+ CLOCK_REALTIME_ALARM = 0x8 -+ CLOCK_REALTIME_COARSE = 0x5 -+ CLOCK_TAI = 0xb -+ CLOCK_THREAD_CPUTIME_ID = 0x3 -+ CLOCK_TXFROMRX = 0x4 -+ CLOCK_TXINT = 0x3 -+ CLONE_CHILD_CLEARTID = 0x200000 -+ CLONE_CHILD_SETTID = 0x1000000 -+ CLONE_DETACHED = 0x400000 -+ CLONE_FILES = 0x400 -+ CLONE_FS = 0x200 -+ CLONE_IO = 0x80000000 -+ CLONE_NEWCGROUP = 0x2000000 -+ CLONE_NEWIPC = 0x8000000 -+ CLONE_NEWNET = 0x40000000 -+ CLONE_NEWNS = 0x20000 -+ CLONE_NEWPID = 0x20000000 -+ CLONE_NEWUSER = 0x10000000 -+ CLONE_NEWUTS = 0x4000000 -+ CLONE_PARENT = 0x8000 -+ CLONE_PARENT_SETTID = 0x100000 -+ CLONE_PTRACE = 0x2000 -+ CLONE_SETTLS = 0x80000 -+ CLONE_SIGHAND = 0x800 -+ CLONE_SYSVSEM = 0x40000 -+ CLONE_THREAD = 0x10000 -+ CLONE_UNTRACED = 0x800000 -+ CLONE_VFORK = 0x4000 -+ CLONE_VM = 0x100 -+ CMSPAR = 0x40000000 -+ CODA_SUPER_MAGIC = 0x73757245 -+ CR0 = 0x0 -+ CR1 = 0x200 -+ CR2 = 0x400 -+ CR3 = 0x600 -+ CRAMFS_MAGIC = 0x28cd3d45 -+ CRDLY = 0x600 -+ CREAD = 0x80 -+ CRTSCTS = 0x80000000 -+ CS5 = 0x0 -+ CS6 = 0x10 -+ CS7 = 0x20 -+ CS8 = 0x30 -+ CSIGNAL = 0xff -+ CSIZE = 0x30 -+ CSTART = 0x11 -+ CSTATUS = 0x0 -+ CSTOP = 0x13 -+ CSTOPB = 0x40 -+ CSUSP = 0x1a -+ DAXFS_MAGIC = 0x64646178 -+ DEBUGFS_MAGIC = 0x64626720 -+ DEVPTS_SUPER_MAGIC = 0x1cd1 -+ DT_BLK = 0x6 -+ DT_CHR = 0x2 -+ DT_DIR = 0x4 -+ DT_FIFO = 0x1 -+ DT_LNK = 0xa -+ DT_REG = 0x8 -+ DT_SOCK = 0xc -+ DT_UNKNOWN = 0x0 -+ DT_WHT = 0xe -+ ECHO = 0x8 -+ ECHOCTL = 0x200 -+ ECHOE = 0x10 -+ ECHOK = 0x20 -+ ECHOKE = 0x800 -+ ECHONL = 0x40 -+ ECHOPRT = 0x400 -+ ECRYPTFS_SUPER_MAGIC = 0xf15f -+ EFD_CLOEXEC = 0x80000 -+ EFD_NONBLOCK = 0x800 -+ EFD_SEMAPHORE = 0x1 -+ EFIVARFS_MAGIC = 0xde5e81e4 -+ EFS_SUPER_MAGIC = 0x414a53 -+ ENCODING_DEFAULT = 0x0 -+ ENCODING_FM_MARK = 0x3 -+ ENCODING_FM_SPACE = 0x4 -+ ENCODING_MANCHESTER = 0x5 -+ ENCODING_NRZ = 0x1 -+ ENCODING_NRZI = 0x2 -+ EPOLLERR = 0x8 -+ EPOLLET = 0x80000000 -+ EPOLLEXCLUSIVE = 0x10000000 -+ EPOLLHUP = 0x10 -+ EPOLLIN = 0x1 -+ EPOLLMSG = 0x400 -+ EPOLLONESHOT = 0x40000000 -+ EPOLLOUT = 0x4 -+ EPOLLPRI = 0x2 -+ EPOLLRDBAND = 0x80 -+ EPOLLRDHUP = 0x2000 -+ EPOLLRDNORM = 0x40 -+ EPOLLWAKEUP = 0x20000000 -+ EPOLLWRBAND = 0x200 -+ EPOLLWRNORM = 0x100 -+ EPOLL_CLOEXEC = 0x80000 -+ EPOLL_CTL_ADD = 0x1 -+ EPOLL_CTL_DEL = 0x2 -+ EPOLL_CTL_MOD = 0x3 -+ ETH_P_1588 = 0x88f7 -+ ETH_P_8021AD = 0x88a8 -+ ETH_P_8021AH = 0x88e7 -+ ETH_P_8021Q = 0x8100 -+ ETH_P_80221 = 0x8917 -+ ETH_P_802_2 = 0x4 -+ ETH_P_802_3 = 0x1 -+ ETH_P_802_3_MIN = 0x600 -+ ETH_P_802_EX1 = 0x88b5 -+ ETH_P_AARP = 0x80f3 -+ ETH_P_AF_IUCV = 0xfbfb -+ ETH_P_ALL = 0x3 -+ ETH_P_AOE = 0x88a2 -+ ETH_P_ARCNET = 0x1a -+ ETH_P_ARP = 0x806 -+ ETH_P_ATALK = 0x809b -+ ETH_P_ATMFATE = 0x8884 -+ ETH_P_ATMMPOA = 0x884c -+ ETH_P_AX25 = 0x2 -+ ETH_P_BATMAN = 0x4305 -+ ETH_P_BPQ = 0x8ff -+ ETH_P_CAIF = 0xf7 -+ ETH_P_CAN = 0xc -+ ETH_P_CANFD = 0xd -+ ETH_P_CONTROL = 0x16 -+ ETH_P_CUST = 0x6006 -+ ETH_P_DDCMP = 0x6 -+ ETH_P_DEC = 0x6000 -+ ETH_P_DIAG = 0x6005 -+ ETH_P_DNA_DL = 0x6001 -+ ETH_P_DNA_RC = 0x6002 -+ ETH_P_DNA_RT = 0x6003 -+ ETH_P_DSA = 0x1b -+ ETH_P_ECONET = 0x18 -+ ETH_P_EDSA = 0xdada -+ ETH_P_ERSPAN = 0x88be -+ ETH_P_ERSPAN2 = 0x22eb -+ ETH_P_FCOE = 0x8906 -+ ETH_P_FIP = 0x8914 -+ ETH_P_HDLC = 0x19 -+ ETH_P_HSR = 0x892f -+ ETH_P_IBOE = 0x8915 -+ ETH_P_IEEE802154 = 0xf6 -+ ETH_P_IEEEPUP = 0xa00 -+ ETH_P_IEEEPUPAT = 0xa01 -+ ETH_P_IFE = 0xed3e -+ ETH_P_IP = 0x800 -+ ETH_P_IPV6 = 0x86dd -+ ETH_P_IPX = 0x8137 -+ ETH_P_IRDA = 0x17 -+ ETH_P_LAT = 0x6004 -+ ETH_P_LINK_CTL = 0x886c -+ ETH_P_LOCALTALK = 0x9 -+ ETH_P_LOOP = 0x60 -+ ETH_P_LOOPBACK = 0x9000 -+ ETH_P_MACSEC = 0x88e5 -+ ETH_P_MAP = 0xf9 -+ ETH_P_MOBITEX = 0x15 -+ ETH_P_MPLS_MC = 0x8848 -+ ETH_P_MPLS_UC = 0x8847 -+ ETH_P_MVRP = 0x88f5 -+ ETH_P_NCSI = 0x88f8 -+ ETH_P_NSH = 0x894f -+ ETH_P_PAE = 0x888e -+ ETH_P_PAUSE = 0x8808 -+ ETH_P_PHONET = 0xf5 -+ ETH_P_PPPTALK = 0x10 -+ ETH_P_PPP_DISC = 0x8863 -+ ETH_P_PPP_MP = 0x8 -+ ETH_P_PPP_SES = 0x8864 -+ ETH_P_PREAUTH = 0x88c7 -+ ETH_P_PRP = 0x88fb -+ ETH_P_PUP = 0x200 -+ ETH_P_PUPAT = 0x201 -+ ETH_P_QINQ1 = 0x9100 -+ ETH_P_QINQ2 = 0x9200 -+ ETH_P_QINQ3 = 0x9300 -+ ETH_P_RARP = 0x8035 -+ ETH_P_SCA = 0x6007 -+ ETH_P_SLOW = 0x8809 -+ ETH_P_SNAP = 0x5 -+ ETH_P_TDLS = 0x890d -+ ETH_P_TEB = 0x6558 -+ ETH_P_TIPC = 0x88ca -+ ETH_P_TRAILER = 0x1c -+ ETH_P_TR_802_2 = 0x11 -+ ETH_P_TSN = 0x22f0 -+ ETH_P_WAN_PPP = 0x7 -+ ETH_P_WCCP = 0x883e -+ ETH_P_X25 = 0x805 -+ ETH_P_XDSA = 0xf8 -+ EXABYTE_ENABLE_NEST = 0xf0 -+ EXT2_SUPER_MAGIC = 0xef53 -+ EXT3_SUPER_MAGIC = 0xef53 -+ EXT4_SUPER_MAGIC = 0xef53 -+ EXTA = 0xe -+ EXTB = 0xf -+ EXTPROC = 0x10000 -+ F2FS_SUPER_MAGIC = 0xf2f52010 -+ FALLOC_FL_COLLAPSE_RANGE = 0x8 -+ FALLOC_FL_INSERT_RANGE = 0x20 -+ FALLOC_FL_KEEP_SIZE = 0x1 -+ FALLOC_FL_NO_HIDE_STALE = 0x4 -+ FALLOC_FL_PUNCH_HOLE = 0x2 -+ FALLOC_FL_UNSHARE_RANGE = 0x40 -+ FALLOC_FL_ZERO_RANGE = 0x10 -+ FD_CLOEXEC = 0x1 -+ FD_SETSIZE = 0x400 -+ FF0 = 0x0 -+ FF1 = 0x8000 -+ FFDLY = 0x8000 -+ FLUSHO = 0x1000 -+ FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 -+ FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 -+ FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 -+ FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 -+ FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 -+ FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 -+ FS_ENCRYPTION_MODE_INVALID = 0x0 -+ FS_ENCRYPTION_MODE_SPECK128_256_CTS = 0x8 -+ FS_ENCRYPTION_MODE_SPECK128_256_XTS = 0x7 -+ FS_IOC_GET_ENCRYPTION_POLICY = 0x400c6615 -+ FS_IOC_GET_ENCRYPTION_PWSALT = 0x40106614 -+ FS_IOC_SET_ENCRYPTION_POLICY = 0x800c6613 -+ FS_KEY_DESCRIPTOR_SIZE = 0x8 -+ FS_KEY_DESC_PREFIX = "fscrypt:" -+ FS_KEY_DESC_PREFIX_SIZE = 0x8 -+ FS_MAX_KEY_SIZE = 0x40 -+ FS_POLICY_FLAGS_PAD_16 = 0x2 -+ FS_POLICY_FLAGS_PAD_32 = 0x3 -+ FS_POLICY_FLAGS_PAD_4 = 0x0 -+ FS_POLICY_FLAGS_PAD_8 = 0x1 -+ FS_POLICY_FLAGS_PAD_MASK = 0x3 -+ FS_POLICY_FLAGS_VALID = 0x3 -+ FUTEXFS_SUPER_MAGIC = 0xbad1dea -+ F_ADD_SEALS = 0x409 -+ F_DUPFD = 0x0 -+ F_DUPFD_CLOEXEC = 0x406 -+ F_EXLCK = 0x4 -+ F_GETFD = 0x1 -+ F_GETFL = 0x3 -+ F_GETLEASE = 0x401 -+ F_GETLK = 0x5 -+ F_GETLK64 = 0x5 -+ F_GETOWN = 0x9 -+ F_GETOWN_EX = 0x10 -+ F_GETPIPE_SZ = 0x408 -+ F_GETSIG = 0xb -+ F_GET_FILE_RW_HINT = 0x40d -+ F_GET_RW_HINT = 0x40b -+ F_GET_SEALS = 0x40a -+ F_LOCK = 0x1 -+ F_NOTIFY = 0x402 -+ F_OFD_GETLK = 0x24 -+ F_OFD_SETLK = 0x25 -+ F_OFD_SETLKW = 0x26 -+ F_OK = 0x0 -+ F_RDLCK = 0x0 -+ F_SEAL_GROW = 0x4 -+ F_SEAL_SEAL = 0x1 -+ F_SEAL_SHRINK = 0x2 -+ F_SEAL_WRITE = 0x8 -+ F_SETFD = 0x2 -+ F_SETFL = 0x4 -+ F_SETLEASE = 0x400 -+ F_SETLK = 0x6 -+ F_SETLK64 = 0x6 -+ F_SETLKW = 0x7 -+ F_SETLKW64 = 0x7 -+ F_SETOWN = 0x8 -+ F_SETOWN_EX = 0xf -+ F_SETPIPE_SZ = 0x407 -+ F_SETSIG = 0xa -+ F_SET_FILE_RW_HINT = 0x40e -+ F_SET_RW_HINT = 0x40c -+ F_SHLCK = 0x8 -+ F_TEST = 0x3 -+ F_TLOCK = 0x2 -+ F_ULOCK = 0x0 -+ F_UNLCK = 0x2 -+ F_WRLCK = 0x1 -+ GENL_ADMIN_PERM = 0x1 -+ GENL_CMD_CAP_DO = 0x2 -+ GENL_CMD_CAP_DUMP = 0x4 -+ GENL_CMD_CAP_HASPOL = 0x8 -+ GENL_HDRLEN = 0x4 -+ GENL_ID_CTRL = 0x10 -+ GENL_ID_PMCRAID = 0x12 -+ GENL_ID_VFS_DQUOT = 0x11 -+ GENL_MAX_ID = 0x3ff -+ GENL_MIN_ID = 0x10 -+ GENL_NAMSIZ = 0x10 -+ GENL_START_ALLOC = 0x13 -+ GENL_UNS_ADMIN_PERM = 0x10 -+ GRND_NONBLOCK = 0x1 -+ GRND_RANDOM = 0x2 -+ HDIO_DRIVE_CMD = 0x31f -+ HDIO_DRIVE_CMD_AEB = 0x31e -+ HDIO_DRIVE_CMD_HDR_SIZE = 0x4 -+ HDIO_DRIVE_HOB_HDR_SIZE = 0x8 -+ HDIO_DRIVE_RESET = 0x31c -+ HDIO_DRIVE_TASK = 0x31e -+ HDIO_DRIVE_TASKFILE = 0x31d -+ HDIO_DRIVE_TASK_HDR_SIZE = 0x8 -+ HDIO_GETGEO = 0x301 -+ HDIO_GET_32BIT = 0x309 -+ HDIO_GET_ACOUSTIC = 0x30f -+ HDIO_GET_ADDRESS = 0x310 -+ HDIO_GET_BUSSTATE = 0x31a -+ HDIO_GET_DMA = 0x30b -+ HDIO_GET_IDENTITY = 0x30d -+ HDIO_GET_KEEPSETTINGS = 0x308 -+ HDIO_GET_MULTCOUNT = 0x304 -+ HDIO_GET_NICE = 0x30c -+ HDIO_GET_NOWERR = 0x30a -+ HDIO_GET_QDMA = 0x305 -+ HDIO_GET_UNMASKINTR = 0x302 -+ HDIO_GET_WCACHE = 0x30e -+ HDIO_OBSOLETE_IDENTITY = 0x307 -+ HDIO_SCAN_HWIF = 0x328 -+ HDIO_SET_32BIT = 0x324 -+ HDIO_SET_ACOUSTIC = 0x32c -+ HDIO_SET_ADDRESS = 0x32f -+ HDIO_SET_BUSSTATE = 0x32d -+ HDIO_SET_DMA = 0x326 -+ HDIO_SET_KEEPSETTINGS = 0x323 -+ HDIO_SET_MULTCOUNT = 0x321 -+ HDIO_SET_NICE = 0x329 -+ HDIO_SET_NOWERR = 0x325 -+ HDIO_SET_PIO_MODE = 0x327 -+ HDIO_SET_QDMA = 0x32e -+ HDIO_SET_UNMASKINTR = 0x322 -+ HDIO_SET_WCACHE = 0x32b -+ HDIO_SET_XFER = 0x306 -+ HDIO_TRISTATE_HWIF = 0x31b -+ HDIO_UNREGISTER_HWIF = 0x32a -+ HOSTFS_SUPER_MAGIC = 0xc0ffee -+ HPFS_SUPER_MAGIC = 0xf995e849 -+ HUGETLBFS_MAGIC = 0x958458f6 -+ HUPCL = 0x400 -+ IBSHIFT = 0x10 -+ ICANON = 0x2 -+ ICMPV6_FILTER = 0x1 -+ ICRNL = 0x100 -+ IEXTEN = 0x8000 -+ IFA_F_DADFAILED = 0x8 -+ IFA_F_DEPRECATED = 0x20 -+ IFA_F_HOMEADDRESS = 0x10 -+ IFA_F_MANAGETEMPADDR = 0x100 -+ IFA_F_MCAUTOJOIN = 0x400 -+ IFA_F_NODAD = 0x2 -+ IFA_F_NOPREFIXROUTE = 0x200 -+ IFA_F_OPTIMISTIC = 0x4 -+ IFA_F_PERMANENT = 0x80 -+ IFA_F_SECONDARY = 0x1 -+ IFA_F_STABLE_PRIVACY = 0x800 -+ IFA_F_TEMPORARY = 0x1 -+ IFA_F_TENTATIVE = 0x40 -+ IFA_MAX = 0xa -+ IFF_ALLMULTI = 0x200 -+ IFF_ATTACH_QUEUE = 0x200 -+ IFF_AUTOMEDIA = 0x4000 -+ IFF_BROADCAST = 0x2 -+ IFF_DEBUG = 0x4 -+ IFF_DETACH_QUEUE = 0x400 -+ IFF_DORMANT = 0x20000 -+ IFF_DYNAMIC = 0x8000 -+ IFF_ECHO = 0x40000 -+ IFF_LOOPBACK = 0x8 -+ IFF_LOWER_UP = 0x10000 -+ IFF_MASTER = 0x400 -+ IFF_MULTICAST = 0x1000 -+ IFF_MULTI_QUEUE = 0x100 -+ IFF_NAPI = 0x10 -+ IFF_NAPI_FRAGS = 0x20 -+ IFF_NOARP = 0x80 -+ IFF_NOFILTER = 0x1000 -+ IFF_NOTRAILERS = 0x20 -+ IFF_NO_PI = 0x1000 -+ IFF_ONE_QUEUE = 0x2000 -+ IFF_PERSIST = 0x800 -+ IFF_POINTOPOINT = 0x10 -+ IFF_PORTSEL = 0x2000 -+ IFF_PROMISC = 0x100 -+ IFF_RUNNING = 0x40 -+ IFF_SLAVE = 0x800 -+ IFF_TAP = 0x2 -+ IFF_TUN = 0x1 -+ IFF_TUN_EXCL = 0x8000 -+ IFF_UP = 0x1 -+ IFF_VNET_HDR = 0x4000 -+ IFF_VOLATILE = 0x70c5a -+ IFNAMSIZ = 0x10 -+ IGNBRK = 0x1 -+ IGNCR = 0x80 -+ IGNPAR = 0x4 -+ IMAXBEL = 0x2000 -+ INLCR = 0x40 -+ INPCK = 0x10 -+ IN_ACCESS = 0x1 -+ IN_ALL_EVENTS = 0xfff -+ IN_ATTRIB = 0x4 -+ IN_CLASSA_HOST = 0xffffff -+ IN_CLASSA_MAX = 0x80 -+ IN_CLASSA_NET = 0xff000000 -+ IN_CLASSA_NSHIFT = 0x18 -+ IN_CLASSB_HOST = 0xffff -+ IN_CLASSB_MAX = 0x10000 -+ IN_CLASSB_NET = 0xffff0000 -+ IN_CLASSB_NSHIFT = 0x10 -+ IN_CLASSC_HOST = 0xff -+ IN_CLASSC_NET = 0xffffff00 -+ IN_CLASSC_NSHIFT = 0x8 -+ IN_CLOEXEC = 0x80000 -+ IN_CLOSE = 0x18 -+ IN_CLOSE_NOWRITE = 0x10 -+ IN_CLOSE_WRITE = 0x8 -+ IN_CREATE = 0x100 -+ IN_DELETE = 0x200 -+ IN_DELETE_SELF = 0x400 -+ IN_DONT_FOLLOW = 0x2000000 -+ IN_EXCL_UNLINK = 0x4000000 -+ IN_IGNORED = 0x8000 -+ IN_ISDIR = 0x40000000 -+ IN_LOOPBACKNET = 0x7f -+ IN_MASK_ADD = 0x20000000 -+ IN_MASK_CREATE = 0x10000000 -+ IN_MODIFY = 0x2 -+ IN_MOVE = 0xc0 -+ IN_MOVED_FROM = 0x40 -+ IN_MOVED_TO = 0x80 -+ IN_MOVE_SELF = 0x800 -+ IN_NONBLOCK = 0x800 -+ IN_ONESHOT = 0x80000000 -+ IN_ONLYDIR = 0x1000000 -+ IN_OPEN = 0x20 -+ IN_Q_OVERFLOW = 0x4000 -+ IN_UNMOUNT = 0x2000 -+ IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 -+ IPPROTO_AH = 0x33 -+ IPPROTO_BEETPH = 0x5e -+ IPPROTO_COMP = 0x6c -+ IPPROTO_DCCP = 0x21 -+ IPPROTO_DSTOPTS = 0x3c -+ IPPROTO_EGP = 0x8 -+ IPPROTO_ENCAP = 0x62 -+ IPPROTO_ESP = 0x32 -+ IPPROTO_FRAGMENT = 0x2c -+ IPPROTO_GRE = 0x2f -+ IPPROTO_HOPOPTS = 0x0 -+ IPPROTO_ICMP = 0x1 -+ IPPROTO_ICMPV6 = 0x3a -+ IPPROTO_IDP = 0x16 -+ IPPROTO_IGMP = 0x2 -+ IPPROTO_IP = 0x0 -+ IPPROTO_IPIP = 0x4 -+ IPPROTO_IPV6 = 0x29 -+ IPPROTO_MH = 0x87 -+ IPPROTO_MPLS = 0x89 -+ IPPROTO_MTP = 0x5c -+ IPPROTO_NONE = 0x3b -+ IPPROTO_PIM = 0x67 -+ IPPROTO_PUP = 0xc -+ IPPROTO_RAW = 0xff -+ IPPROTO_ROUTING = 0x2b -+ IPPROTO_RSVP = 0x2e -+ IPPROTO_SCTP = 0x84 -+ IPPROTO_TCP = 0x6 -+ IPPROTO_TP = 0x1d -+ IPPROTO_UDP = 0x11 -+ IPPROTO_UDPLITE = 0x88 -+ IPV6_2292DSTOPTS = 0x4 -+ IPV6_2292HOPLIMIT = 0x8 -+ IPV6_2292HOPOPTS = 0x3 -+ IPV6_2292PKTINFO = 0x2 -+ IPV6_2292PKTOPTIONS = 0x6 -+ IPV6_2292RTHDR = 0x5 -+ IPV6_ADDRFORM = 0x1 -+ IPV6_ADDR_PREFERENCES = 0x48 -+ IPV6_ADD_MEMBERSHIP = 0x14 -+ IPV6_AUTHHDR = 0xa -+ IPV6_AUTOFLOWLABEL = 0x46 -+ IPV6_CHECKSUM = 0x7 -+ IPV6_DONTFRAG = 0x3e -+ IPV6_DROP_MEMBERSHIP = 0x15 -+ IPV6_DSTOPTS = 0x3b -+ IPV6_FREEBIND = 0x4e -+ IPV6_HDRINCL = 0x24 -+ IPV6_HOPLIMIT = 0x34 -+ IPV6_HOPOPTS = 0x36 -+ IPV6_IPSEC_POLICY = 0x22 -+ IPV6_JOIN_ANYCAST = 0x1b -+ IPV6_JOIN_GROUP = 0x14 -+ IPV6_LEAVE_ANYCAST = 0x1c -+ IPV6_LEAVE_GROUP = 0x15 -+ IPV6_MINHOPCOUNT = 0x49 -+ IPV6_MTU = 0x18 -+ IPV6_MTU_DISCOVER = 0x17 -+ IPV6_MULTICAST_ALL = 0x1d -+ IPV6_MULTICAST_HOPS = 0x12 -+ IPV6_MULTICAST_IF = 0x11 -+ IPV6_MULTICAST_LOOP = 0x13 -+ IPV6_NEXTHOP = 0x9 -+ IPV6_ORIGDSTADDR = 0x4a -+ IPV6_PATHMTU = 0x3d -+ IPV6_PKTINFO = 0x32 -+ IPV6_PMTUDISC_DO = 0x2 -+ IPV6_PMTUDISC_DONT = 0x0 -+ IPV6_PMTUDISC_INTERFACE = 0x4 -+ IPV6_PMTUDISC_OMIT = 0x5 -+ IPV6_PMTUDISC_PROBE = 0x3 -+ IPV6_PMTUDISC_WANT = 0x1 -+ IPV6_RECVDSTOPTS = 0x3a -+ IPV6_RECVERR = 0x19 -+ IPV6_RECVFRAGSIZE = 0x4d -+ IPV6_RECVHOPLIMIT = 0x33 -+ IPV6_RECVHOPOPTS = 0x35 -+ IPV6_RECVORIGDSTADDR = 0x4a -+ IPV6_RECVPATHMTU = 0x3c -+ IPV6_RECVPKTINFO = 0x31 -+ IPV6_RECVRTHDR = 0x38 -+ IPV6_RECVTCLASS = 0x42 -+ IPV6_ROUTER_ALERT = 0x16 -+ IPV6_RTHDR = 0x39 -+ IPV6_RTHDRDSTOPTS = 0x37 -+ IPV6_RTHDR_LOOSE = 0x0 -+ IPV6_RTHDR_STRICT = 0x1 -+ IPV6_RTHDR_TYPE_0 = 0x0 -+ IPV6_RXDSTOPTS = 0x3b -+ IPV6_RXHOPOPTS = 0x36 -+ IPV6_TCLASS = 0x43 -+ IPV6_TRANSPARENT = 0x4b -+ IPV6_UNICAST_HOPS = 0x10 -+ IPV6_UNICAST_IF = 0x4c -+ IPV6_V6ONLY = 0x1a -+ IPV6_XFRM_POLICY = 0x23 -+ IP_ADD_MEMBERSHIP = 0x23 -+ IP_ADD_SOURCE_MEMBERSHIP = 0x27 -+ IP_BIND_ADDRESS_NO_PORT = 0x18 -+ IP_BLOCK_SOURCE = 0x26 -+ IP_CHECKSUM = 0x17 -+ IP_DEFAULT_MULTICAST_LOOP = 0x1 -+ IP_DEFAULT_MULTICAST_TTL = 0x1 -+ IP_DF = 0x4000 -+ IP_DROP_MEMBERSHIP = 0x24 -+ IP_DROP_SOURCE_MEMBERSHIP = 0x28 -+ IP_FREEBIND = 0xf -+ IP_HDRINCL = 0x3 -+ IP_IPSEC_POLICY = 0x10 -+ IP_MAXPACKET = 0xffff -+ IP_MAX_MEMBERSHIPS = 0x14 -+ IP_MF = 0x2000 -+ IP_MINTTL = 0x15 -+ IP_MSFILTER = 0x29 -+ IP_MSS = 0x240 -+ IP_MTU = 0xe -+ IP_MTU_DISCOVER = 0xa -+ IP_MULTICAST_ALL = 0x31 -+ IP_MULTICAST_IF = 0x20 -+ IP_MULTICAST_LOOP = 0x22 -+ IP_MULTICAST_TTL = 0x21 -+ IP_NODEFRAG = 0x16 -+ IP_OFFMASK = 0x1fff -+ IP_OPTIONS = 0x4 -+ IP_ORIGDSTADDR = 0x14 -+ IP_PASSSEC = 0x12 -+ IP_PKTINFO = 0x8 -+ IP_PKTOPTIONS = 0x9 -+ IP_PMTUDISC = 0xa -+ IP_PMTUDISC_DO = 0x2 -+ IP_PMTUDISC_DONT = 0x0 -+ IP_PMTUDISC_INTERFACE = 0x4 -+ IP_PMTUDISC_OMIT = 0x5 -+ IP_PMTUDISC_PROBE = 0x3 -+ IP_PMTUDISC_WANT = 0x1 -+ IP_RECVERR = 0xb -+ IP_RECVFRAGSIZE = 0x19 -+ IP_RECVOPTS = 0x6 -+ IP_RECVORIGDSTADDR = 0x14 -+ IP_RECVRETOPTS = 0x7 -+ IP_RECVTOS = 0xd -+ IP_RECVTTL = 0xc -+ IP_RETOPTS = 0x7 -+ IP_RF = 0x8000 -+ IP_ROUTER_ALERT = 0x5 -+ IP_TOS = 0x1 -+ IP_TRANSPARENT = 0x13 -+ IP_TTL = 0x2 -+ IP_UNBLOCK_SOURCE = 0x25 -+ IP_UNICAST_IF = 0x32 -+ IP_XFRM_POLICY = 0x11 -+ ISIG = 0x1 -+ ISOFS_SUPER_MAGIC = 0x9660 -+ ISTRIP = 0x20 -+ IUCLC = 0x200 -+ IUTF8 = 0x4000 -+ IXANY = 0x800 -+ IXOFF = 0x1000 -+ IXON = 0x400 -+ JFFS2_SUPER_MAGIC = 0x72b6 -+ KEXEC_ARCH_386 = 0x30000 -+ KEXEC_ARCH_68K = 0x40000 -+ KEXEC_ARCH_AARCH64 = 0xb70000 -+ KEXEC_ARCH_ARM = 0x280000 -+ KEXEC_ARCH_DEFAULT = 0x0 -+ KEXEC_ARCH_IA_64 = 0x320000 -+ KEXEC_ARCH_MASK = 0xffff0000 -+ KEXEC_ARCH_MIPS = 0x80000 -+ KEXEC_ARCH_MIPS_LE = 0xa0000 -+ KEXEC_ARCH_PPC = 0x140000 -+ KEXEC_ARCH_PPC64 = 0x150000 -+ KEXEC_ARCH_S390 = 0x160000 -+ KEXEC_ARCH_SH = 0x2a0000 -+ KEXEC_ARCH_X86_64 = 0x3e0000 -+ KEXEC_FILE_NO_INITRAMFS = 0x4 -+ KEXEC_FILE_ON_CRASH = 0x2 -+ KEXEC_FILE_UNLOAD = 0x1 -+ KEXEC_ON_CRASH = 0x1 -+ KEXEC_PRESERVE_CONTEXT = 0x2 -+ KEXEC_SEGMENT_MAX = 0x10 -+ KEYCTL_ASSUME_AUTHORITY = 0x10 -+ KEYCTL_CHOWN = 0x4 -+ KEYCTL_CLEAR = 0x7 -+ KEYCTL_DESCRIBE = 0x6 -+ KEYCTL_DH_COMPUTE = 0x17 -+ KEYCTL_GET_KEYRING_ID = 0x0 -+ KEYCTL_GET_PERSISTENT = 0x16 -+ KEYCTL_GET_SECURITY = 0x11 -+ KEYCTL_INSTANTIATE = 0xc -+ KEYCTL_INSTANTIATE_IOV = 0x14 -+ KEYCTL_INVALIDATE = 0x15 -+ KEYCTL_JOIN_SESSION_KEYRING = 0x1 -+ KEYCTL_LINK = 0x8 -+ KEYCTL_NEGATE = 0xd -+ KEYCTL_PKEY_DECRYPT = 0x1a -+ KEYCTL_PKEY_ENCRYPT = 0x19 -+ KEYCTL_PKEY_QUERY = 0x18 -+ KEYCTL_PKEY_SIGN = 0x1b -+ KEYCTL_PKEY_VERIFY = 0x1c -+ KEYCTL_READ = 0xb -+ KEYCTL_REJECT = 0x13 -+ KEYCTL_RESTRICT_KEYRING = 0x1d -+ KEYCTL_REVOKE = 0x3 -+ KEYCTL_SEARCH = 0xa -+ KEYCTL_SESSION_TO_PARENT = 0x12 -+ KEYCTL_SETPERM = 0x5 -+ KEYCTL_SET_REQKEY_KEYRING = 0xe -+ KEYCTL_SET_TIMEOUT = 0xf -+ KEYCTL_SUPPORTS_DECRYPT = 0x2 -+ KEYCTL_SUPPORTS_ENCRYPT = 0x1 -+ KEYCTL_SUPPORTS_SIGN = 0x4 -+ KEYCTL_SUPPORTS_VERIFY = 0x8 -+ KEYCTL_UNLINK = 0x9 -+ KEYCTL_UPDATE = 0x2 -+ KEY_REQKEY_DEFL_DEFAULT = 0x0 -+ KEY_REQKEY_DEFL_GROUP_KEYRING = 0x6 -+ KEY_REQKEY_DEFL_NO_CHANGE = -0x1 -+ KEY_REQKEY_DEFL_PROCESS_KEYRING = 0x2 -+ KEY_REQKEY_DEFL_REQUESTOR_KEYRING = 0x7 -+ KEY_REQKEY_DEFL_SESSION_KEYRING = 0x3 -+ KEY_REQKEY_DEFL_THREAD_KEYRING = 0x1 -+ KEY_REQKEY_DEFL_USER_KEYRING = 0x4 -+ KEY_REQKEY_DEFL_USER_SESSION_KEYRING = 0x5 -+ KEY_SPEC_GROUP_KEYRING = -0x6 -+ KEY_SPEC_PROCESS_KEYRING = -0x2 -+ KEY_SPEC_REQKEY_AUTH_KEY = -0x7 -+ KEY_SPEC_REQUESTOR_KEYRING = -0x8 -+ KEY_SPEC_SESSION_KEYRING = -0x3 -+ KEY_SPEC_THREAD_KEYRING = -0x1 -+ KEY_SPEC_USER_KEYRING = -0x4 -+ KEY_SPEC_USER_SESSION_KEYRING = -0x5 -+ LINUX_REBOOT_CMD_CAD_OFF = 0x0 -+ LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef -+ LINUX_REBOOT_CMD_HALT = 0xcdef0123 -+ LINUX_REBOOT_CMD_KEXEC = 0x45584543 -+ LINUX_REBOOT_CMD_POWER_OFF = 0x4321fedc -+ LINUX_REBOOT_CMD_RESTART = 0x1234567 -+ LINUX_REBOOT_CMD_RESTART2 = 0xa1b2c3d4 -+ LINUX_REBOOT_CMD_SW_SUSPEND = 0xd000fce2 -+ LINUX_REBOOT_MAGIC1 = 0xfee1dead -+ LINUX_REBOOT_MAGIC2 = 0x28121969 -+ LOCK_EX = 0x2 -+ LOCK_NB = 0x4 -+ LOCK_SH = 0x1 -+ LOCK_UN = 0x8 -+ MADV_DODUMP = 0x11 -+ MADV_DOFORK = 0xb -+ MADV_DONTDUMP = 0x10 -+ MADV_DONTFORK = 0xa -+ MADV_DONTNEED = 0x4 -+ MADV_FREE = 0x8 -+ MADV_HUGEPAGE = 0xe -+ MADV_HWPOISON = 0x64 -+ MADV_KEEPONFORK = 0x13 -+ MADV_MERGEABLE = 0xc -+ MADV_NOHUGEPAGE = 0xf -+ MADV_NORMAL = 0x0 -+ MADV_RANDOM = 0x1 -+ MADV_REMOVE = 0x9 -+ MADV_SEQUENTIAL = 0x2 -+ MADV_UNMERGEABLE = 0xd -+ MADV_WILLNEED = 0x3 -+ MADV_WIPEONFORK = 0x12 -+ MAP_ANON = 0x20 -+ MAP_ANONYMOUS = 0x20 -+ MAP_DENYWRITE = 0x800 -+ MAP_EXECUTABLE = 0x1000 -+ MAP_FILE = 0x0 -+ MAP_FIXED = 0x10 -+ MAP_FIXED_NOREPLACE = 0x100000 -+ MAP_GROWSDOWN = 0x100 -+ MAP_HUGETLB = 0x40000 -+ MAP_HUGE_MASK = 0x3f -+ MAP_HUGE_SHIFT = 0x1a -+ MAP_LOCKED = 0x2000 -+ MAP_NONBLOCK = 0x10000 -+ MAP_NORESERVE = 0x4000 -+ MAP_POPULATE = 0x8000 -+ MAP_PRIVATE = 0x2 -+ MAP_SHARED = 0x1 -+ MAP_SHARED_VALIDATE = 0x3 -+ MAP_STACK = 0x20000 -+ MAP_SYNC = 0x80000 -+ MAP_TYPE = 0xf -+ MCL_CURRENT = 0x1 -+ MCL_FUTURE = 0x2 -+ MCL_ONFAULT = 0x4 -+ MFD_ALLOW_SEALING = 0x2 -+ MFD_CLOEXEC = 0x1 -+ MFD_HUGETLB = 0x4 -+ MFD_HUGE_16GB = -0x78000000 -+ MFD_HUGE_16MB = 0x60000000 -+ MFD_HUGE_1GB = 0x78000000 -+ MFD_HUGE_1MB = 0x50000000 -+ MFD_HUGE_256MB = 0x70000000 -+ MFD_HUGE_2GB = 0x7c000000 -+ MFD_HUGE_2MB = 0x54000000 -+ MFD_HUGE_32MB = 0x64000000 -+ MFD_HUGE_512KB = 0x4c000000 -+ MFD_HUGE_512MB = 0x74000000 -+ MFD_HUGE_64KB = 0x40000000 -+ MFD_HUGE_8MB = 0x5c000000 -+ MFD_HUGE_MASK = 0x3f -+ MFD_HUGE_SHIFT = 0x1a -+ MINIX2_SUPER_MAGIC = 0x2468 -+ MINIX2_SUPER_MAGIC2 = 0x2478 -+ MINIX3_SUPER_MAGIC = 0x4d5a -+ MINIX_SUPER_MAGIC = 0x137f -+ MINIX_SUPER_MAGIC2 = 0x138f -+ MNT_DETACH = 0x2 -+ MNT_EXPIRE = 0x4 -+ MNT_FORCE = 0x1 -+ MODULE_INIT_IGNORE_MODVERSIONS = 0x1 -+ MODULE_INIT_IGNORE_VERMAGIC = 0x2 -+ MSDOS_SUPER_MAGIC = 0x4d44 -+ MSG_BATCH = 0x40000 -+ MSG_CMSG_CLOEXEC = 0x40000000 -+ MSG_CONFIRM = 0x800 -+ MSG_CTRUNC = 0x8 -+ MSG_DONTROUTE = 0x4 -+ MSG_DONTWAIT = 0x40 -+ MSG_EOR = 0x80 -+ MSG_ERRQUEUE = 0x2000 -+ MSG_FASTOPEN = 0x20000000 -+ MSG_FIN = 0x200 -+ MSG_MORE = 0x8000 -+ MSG_NOSIGNAL = 0x4000 -+ MSG_OOB = 0x1 -+ MSG_PEEK = 0x2 -+ MSG_PROXY = 0x10 -+ MSG_RST = 0x1000 -+ MSG_SYN = 0x400 -+ MSG_TRUNC = 0x20 -+ MSG_TRYHARD = 0x4 -+ MSG_WAITALL = 0x100 -+ MSG_WAITFORONE = 0x10000 -+ MSG_ZEROCOPY = 0x4000000 -+ MS_ACTIVE = 0x40000000 -+ MS_ASYNC = 0x1 -+ MS_BIND = 0x1000 -+ MS_BORN = 0x20000000 -+ MS_DIRSYNC = 0x80 -+ MS_INVALIDATE = 0x2 -+ MS_I_VERSION = 0x800000 -+ MS_KERNMOUNT = 0x400000 -+ MS_LAZYTIME = 0x2000000 -+ MS_MANDLOCK = 0x40 -+ MS_MGC_MSK = 0xffff0000 -+ MS_MGC_VAL = 0xc0ed0000 -+ MS_MOVE = 0x2000 -+ MS_NOATIME = 0x400 -+ MS_NODEV = 0x4 -+ MS_NODIRATIME = 0x800 -+ MS_NOEXEC = 0x8 -+ MS_NOREMOTELOCK = 0x8000000 -+ MS_NOSEC = 0x10000000 -+ MS_NOSUID = 0x2 -+ MS_NOUSER = -0x80000000 -+ MS_POSIXACL = 0x10000 -+ MS_PRIVATE = 0x40000 -+ MS_RDONLY = 0x1 -+ MS_REC = 0x4000 -+ MS_RELATIME = 0x200000 -+ MS_REMOUNT = 0x20 -+ MS_RMT_MASK = 0x2800051 -+ MS_SHARED = 0x100000 -+ MS_SILENT = 0x8000 -+ MS_SLAVE = 0x80000 -+ MS_STRICTATIME = 0x1000000 -+ MS_SUBMOUNT = 0x4000000 -+ MS_SYNC = 0x4 -+ MS_SYNCHRONOUS = 0x10 -+ MS_UNBINDABLE = 0x20000 -+ MS_VERBOSE = 0x8000 -+ MTD_INODE_FS_MAGIC = 0x11307854 -+ NAME_MAX = 0xff -+ NCP_SUPER_MAGIC = 0x564c -+ NETLINK_ADD_MEMBERSHIP = 0x1 -+ NETLINK_AUDIT = 0x9 -+ NETLINK_BROADCAST_ERROR = 0x4 -+ NETLINK_CAP_ACK = 0xa -+ NETLINK_CONNECTOR = 0xb -+ NETLINK_CRYPTO = 0x15 -+ NETLINK_DNRTMSG = 0xe -+ NETLINK_DROP_MEMBERSHIP = 0x2 -+ NETLINK_ECRYPTFS = 0x13 -+ NETLINK_EXT_ACK = 0xb -+ NETLINK_FIB_LOOKUP = 0xa -+ NETLINK_FIREWALL = 0x3 -+ NETLINK_GENERIC = 0x10 -+ NETLINK_GET_STRICT_CHK = 0xc -+ NETLINK_INET_DIAG = 0x4 -+ NETLINK_IP6_FW = 0xd -+ NETLINK_ISCSI = 0x8 -+ NETLINK_KOBJECT_UEVENT = 0xf -+ NETLINK_LISTEN_ALL_NSID = 0x8 -+ NETLINK_LIST_MEMBERSHIPS = 0x9 -+ NETLINK_NETFILTER = 0xc -+ NETLINK_NFLOG = 0x5 -+ NETLINK_NO_ENOBUFS = 0x5 -+ NETLINK_PKTINFO = 0x3 -+ NETLINK_RDMA = 0x14 -+ NETLINK_ROUTE = 0x0 -+ NETLINK_RX_RING = 0x6 -+ NETLINK_SCSITRANSPORT = 0x12 -+ NETLINK_SELINUX = 0x7 -+ NETLINK_SMC = 0x16 -+ NETLINK_SOCK_DIAG = 0x4 -+ NETLINK_TX_RING = 0x7 -+ NETLINK_UNUSED = 0x1 -+ NETLINK_USERSOCK = 0x2 -+ NETLINK_XFRM = 0x6 -+ NETNSA_MAX = 0x3 -+ NETNSA_NSID_NOT_ASSIGNED = -0x1 -+ NFNETLINK_V0 = 0x0 -+ NFNLGRP_ACCT_QUOTA = 0x8 -+ NFNLGRP_CONNTRACK_DESTROY = 0x3 -+ NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 -+ NFNLGRP_CONNTRACK_EXP_NEW = 0x4 -+ NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 -+ NFNLGRP_CONNTRACK_NEW = 0x1 -+ NFNLGRP_CONNTRACK_UPDATE = 0x2 -+ NFNLGRP_MAX = 0x9 -+ NFNLGRP_NFTABLES = 0x7 -+ NFNLGRP_NFTRACE = 0x9 -+ NFNLGRP_NONE = 0x0 -+ NFNL_BATCH_MAX = 0x1 -+ NFNL_MSG_BATCH_BEGIN = 0x10 -+ NFNL_MSG_BATCH_END = 0x11 -+ NFNL_NFA_NEST = 0x8000 -+ NFNL_SUBSYS_ACCT = 0x7 -+ NFNL_SUBSYS_COUNT = 0xc -+ NFNL_SUBSYS_CTHELPER = 0x9 -+ NFNL_SUBSYS_CTNETLINK = 0x1 -+ NFNL_SUBSYS_CTNETLINK_EXP = 0x2 -+ NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 -+ NFNL_SUBSYS_IPSET = 0x6 -+ NFNL_SUBSYS_NFTABLES = 0xa -+ NFNL_SUBSYS_NFT_COMPAT = 0xb -+ NFNL_SUBSYS_NONE = 0x0 -+ NFNL_SUBSYS_OSF = 0x5 -+ NFNL_SUBSYS_QUEUE = 0x3 -+ NFNL_SUBSYS_ULOG = 0x4 -+ NFS_SUPER_MAGIC = 0x6969 -+ NILFS_SUPER_MAGIC = 0x3434 -+ NL0 = 0x0 -+ NL1 = 0x100 -+ NLA_ALIGNTO = 0x4 -+ NLA_F_NESTED = 0x8000 -+ NLA_F_NET_BYTEORDER = 0x4000 -+ NLA_HDRLEN = 0x4 -+ NLDLY = 0x100 -+ NLMSG_ALIGNTO = 0x4 -+ NLMSG_DONE = 0x3 -+ NLMSG_ERROR = 0x2 -+ NLMSG_HDRLEN = 0x10 -+ NLMSG_MIN_TYPE = 0x10 -+ NLMSG_NOOP = 0x1 -+ NLMSG_OVERRUN = 0x4 -+ NLM_F_ACK = 0x4 -+ NLM_F_ACK_TLVS = 0x200 -+ NLM_F_APPEND = 0x800 -+ NLM_F_ATOMIC = 0x400 -+ NLM_F_CAPPED = 0x100 -+ NLM_F_CREATE = 0x400 -+ NLM_F_DUMP = 0x300 -+ NLM_F_DUMP_FILTERED = 0x20 -+ NLM_F_DUMP_INTR = 0x10 -+ NLM_F_ECHO = 0x8 -+ NLM_F_EXCL = 0x200 -+ NLM_F_MATCH = 0x200 -+ NLM_F_MULTI = 0x2 -+ NLM_F_NONREC = 0x100 -+ NLM_F_REPLACE = 0x100 -+ NLM_F_REQUEST = 0x1 -+ NLM_F_ROOT = 0x100 -+ NOFLSH = 0x80 -+ NSFS_MAGIC = 0x6e736673 -+ OCFS2_SUPER_MAGIC = 0x7461636f -+ OCRNL = 0x8 -+ OFDEL = 0x80 -+ OFILL = 0x40 -+ OLCUC = 0x2 -+ ONLCR = 0x4 -+ ONLRET = 0x20 -+ ONOCR = 0x10 -+ OPENPROM_SUPER_MAGIC = 0x9fa1 -+ OPOST = 0x1 -+ OVERLAYFS_SUPER_MAGIC = 0x794c7630 -+ O_ACCMODE = 0x3 -+ O_APPEND = 0x400 -+ O_ASYNC = 0x2000 -+ O_CLOEXEC = 0x80000 -+ O_CREAT = 0x40 -+ O_DIRECT = 0x4000 -+ O_DIRECTORY = 0x10000 -+ O_DSYNC = 0x1000 -+ O_EXCL = 0x80 -+ O_FSYNC = 0x101000 -+ O_LARGEFILE = 0x0 -+ O_NDELAY = 0x800 -+ O_NOATIME = 0x40000 -+ O_NOCTTY = 0x100 -+ O_NOFOLLOW = 0x20000 -+ O_NONBLOCK = 0x800 -+ O_PATH = 0x200000 -+ O_RDONLY = 0x0 -+ O_RDWR = 0x2 -+ O_RSYNC = 0x101000 -+ O_SYNC = 0x101000 -+ O_TMPFILE = 0x410000 -+ O_TRUNC = 0x200 -+ O_WRONLY = 0x1 -+ PACKET_ADD_MEMBERSHIP = 0x1 -+ PACKET_AUXDATA = 0x8 -+ PACKET_BROADCAST = 0x1 -+ PACKET_COPY_THRESH = 0x7 -+ PACKET_DROP_MEMBERSHIP = 0x2 -+ PACKET_FANOUT = 0x12 -+ PACKET_FANOUT_CBPF = 0x6 -+ PACKET_FANOUT_CPU = 0x2 -+ PACKET_FANOUT_DATA = 0x16 -+ PACKET_FANOUT_EBPF = 0x7 -+ PACKET_FANOUT_FLAG_DEFRAG = 0x8000 -+ PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 -+ PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 -+ PACKET_FANOUT_HASH = 0x0 -+ PACKET_FANOUT_LB = 0x1 -+ PACKET_FANOUT_QM = 0x5 -+ PACKET_FANOUT_RND = 0x4 -+ PACKET_FANOUT_ROLLOVER = 0x3 -+ PACKET_FASTROUTE = 0x6 -+ PACKET_HDRLEN = 0xb -+ PACKET_HOST = 0x0 -+ PACKET_IGNORE_OUTGOING = 0x17 -+ PACKET_KERNEL = 0x7 -+ PACKET_LOOPBACK = 0x5 -+ PACKET_LOSS = 0xe -+ PACKET_MR_ALLMULTI = 0x2 -+ PACKET_MR_MULTICAST = 0x0 -+ PACKET_MR_PROMISC = 0x1 -+ PACKET_MR_UNICAST = 0x3 -+ PACKET_MULTICAST = 0x2 -+ PACKET_ORIGDEV = 0x9 -+ PACKET_OTHERHOST = 0x3 -+ PACKET_OUTGOING = 0x4 -+ PACKET_QDISC_BYPASS = 0x14 -+ PACKET_RECV_OUTPUT = 0x3 -+ PACKET_RESERVE = 0xc -+ PACKET_ROLLOVER_STATS = 0x15 -+ PACKET_RX_RING = 0x5 -+ PACKET_STATISTICS = 0x6 -+ PACKET_TIMESTAMP = 0x11 -+ PACKET_TX_HAS_OFF = 0x13 -+ PACKET_TX_RING = 0xd -+ PACKET_TX_TIMESTAMP = 0x10 -+ PACKET_USER = 0x6 -+ PACKET_VERSION = 0xa -+ PACKET_VNET_HDR = 0xf -+ PARENB = 0x100 -+ PARITY_CRC16_PR0 = 0x2 -+ PARITY_CRC16_PR0_CCITT = 0x4 -+ PARITY_CRC16_PR1 = 0x3 -+ PARITY_CRC16_PR1_CCITT = 0x5 -+ PARITY_CRC32_PR0_CCITT = 0x6 -+ PARITY_CRC32_PR1_CCITT = 0x7 -+ PARITY_DEFAULT = 0x0 -+ PARITY_NONE = 0x1 -+ PARMRK = 0x8 -+ PARODD = 0x200 -+ PENDIN = 0x4000 -+ PERF_EVENT_IOC_DISABLE = 0x2401 -+ PERF_EVENT_IOC_ENABLE = 0x2400 -+ PERF_EVENT_IOC_ID = 0x80082407 -+ PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x4008240b -+ PERF_EVENT_IOC_PAUSE_OUTPUT = 0x40042409 -+ PERF_EVENT_IOC_PERIOD = 0x40082404 -+ PERF_EVENT_IOC_QUERY_BPF = 0xc008240a -+ PERF_EVENT_IOC_REFRESH = 0x2402 -+ PERF_EVENT_IOC_RESET = 0x2403 -+ PERF_EVENT_IOC_SET_BPF = 0x40042408 -+ PERF_EVENT_IOC_SET_FILTER = 0x40082406 -+ PERF_EVENT_IOC_SET_OUTPUT = 0x2405 -+ PIPEFS_MAGIC = 0x50495045 -+ PPPIOCATTACH = 0x4004743d -+ PPPIOCATTCHAN = 0x40047438 -+ PPPIOCCONNECT = 0x4004743a -+ PPPIOCDETACH = 0x4004743c -+ PPPIOCDISCONN = 0x7439 -+ PPPIOCGASYNCMAP = 0x80047458 -+ PPPIOCGCHAN = 0x80047437 -+ PPPIOCGDEBUG = 0x80047441 -+ PPPIOCGFLAGS = 0x8004745a -+ PPPIOCGIDLE = 0x8010743f -+ PPPIOCGL2TPSTATS = 0x80487436 -+ PPPIOCGMRU = 0x80047453 -+ PPPIOCGNPMODE = 0xc008744c -+ PPPIOCGRASYNCMAP = 0x80047455 -+ PPPIOCGUNIT = 0x80047456 -+ PPPIOCGXASYNCMAP = 0x80207450 -+ PPPIOCNEWUNIT = 0xc004743e -+ PPPIOCSACTIVE = 0x40107446 -+ PPPIOCSASYNCMAP = 0x40047457 -+ PPPIOCSCOMPRESS = 0x4010744d -+ PPPIOCSDEBUG = 0x40047440 -+ PPPIOCSFLAGS = 0x40047459 -+ PPPIOCSMAXCID = 0x40047451 -+ PPPIOCSMRRU = 0x4004743b -+ PPPIOCSMRU = 0x40047452 -+ PPPIOCSNPMODE = 0x4008744b -+ PPPIOCSPASS = 0x40107447 -+ PPPIOCSRASYNCMAP = 0x40047454 -+ PPPIOCSXASYNCMAP = 0x4020744f -+ PPPIOCXFERUNIT = 0x744e -+ PRIO_PGRP = 0x1 -+ PRIO_PROCESS = 0x0 -+ PRIO_USER = 0x2 -+ PROC_SUPER_MAGIC = 0x9fa0 -+ PROT_EXEC = 0x4 -+ PROT_GROWSDOWN = 0x1000000 -+ PROT_GROWSUP = 0x2000000 -+ PROT_NONE = 0x0 -+ PROT_READ = 0x1 -+ PROT_WRITE = 0x2 -+ PR_CAPBSET_DROP = 0x18 -+ PR_CAPBSET_READ = 0x17 -+ PR_CAP_AMBIENT = 0x2f -+ PR_CAP_AMBIENT_CLEAR_ALL = 0x4 -+ PR_CAP_AMBIENT_IS_SET = 0x1 -+ PR_CAP_AMBIENT_LOWER = 0x3 -+ PR_CAP_AMBIENT_RAISE = 0x2 -+ PR_ENDIAN_BIG = 0x0 -+ PR_ENDIAN_LITTLE = 0x1 -+ PR_ENDIAN_PPC_LITTLE = 0x2 -+ PR_FPEMU_NOPRINT = 0x1 -+ PR_FPEMU_SIGFPE = 0x2 -+ PR_FP_EXC_ASYNC = 0x2 -+ PR_FP_EXC_DISABLED = 0x0 -+ PR_FP_EXC_DIV = 0x10000 -+ PR_FP_EXC_INV = 0x100000 -+ PR_FP_EXC_NONRECOV = 0x1 -+ PR_FP_EXC_OVF = 0x20000 -+ PR_FP_EXC_PRECISE = 0x3 -+ PR_FP_EXC_RES = 0x80000 -+ PR_FP_EXC_SW_ENABLE = 0x80 -+ PR_FP_EXC_UND = 0x40000 -+ PR_FP_MODE_FR = 0x1 -+ PR_FP_MODE_FRE = 0x2 -+ PR_GET_CHILD_SUBREAPER = 0x25 -+ PR_GET_DUMPABLE = 0x3 -+ PR_GET_ENDIAN = 0x13 -+ PR_GET_FPEMU = 0x9 -+ PR_GET_FPEXC = 0xb -+ PR_GET_FP_MODE = 0x2e -+ PR_GET_KEEPCAPS = 0x7 -+ PR_GET_NAME = 0x10 -+ PR_GET_NO_NEW_PRIVS = 0x27 -+ PR_GET_PDEATHSIG = 0x2 -+ PR_GET_SECCOMP = 0x15 -+ PR_GET_SECUREBITS = 0x1b -+ PR_GET_SPECULATION_CTRL = 0x34 -+ PR_GET_THP_DISABLE = 0x2a -+ PR_GET_TID_ADDRESS = 0x28 -+ PR_GET_TIMERSLACK = 0x1e -+ PR_GET_TIMING = 0xd -+ PR_GET_TSC = 0x19 -+ PR_GET_UNALIGN = 0x5 -+ PR_MCE_KILL = 0x21 -+ PR_MCE_KILL_CLEAR = 0x0 -+ PR_MCE_KILL_DEFAULT = 0x2 -+ PR_MCE_KILL_EARLY = 0x1 -+ PR_MCE_KILL_GET = 0x22 -+ PR_MCE_KILL_LATE = 0x0 -+ PR_MCE_KILL_SET = 0x1 -+ PR_MPX_DISABLE_MANAGEMENT = 0x2c -+ PR_MPX_ENABLE_MANAGEMENT = 0x2b -+ PR_SET_CHILD_SUBREAPER = 0x24 -+ PR_SET_DUMPABLE = 0x4 -+ PR_SET_ENDIAN = 0x14 -+ PR_SET_FPEMU = 0xa -+ PR_SET_FPEXC = 0xc -+ PR_SET_FP_MODE = 0x2d -+ PR_SET_KEEPCAPS = 0x8 -+ PR_SET_MM = 0x23 -+ PR_SET_MM_ARG_END = 0x9 -+ PR_SET_MM_ARG_START = 0x8 -+ PR_SET_MM_AUXV = 0xc -+ PR_SET_MM_BRK = 0x7 -+ PR_SET_MM_END_CODE = 0x2 -+ PR_SET_MM_END_DATA = 0x4 -+ PR_SET_MM_ENV_END = 0xb -+ PR_SET_MM_ENV_START = 0xa -+ PR_SET_MM_EXE_FILE = 0xd -+ PR_SET_MM_MAP = 0xe -+ PR_SET_MM_MAP_SIZE = 0xf -+ PR_SET_MM_START_BRK = 0x6 -+ PR_SET_MM_START_CODE = 0x1 -+ PR_SET_MM_START_DATA = 0x3 -+ PR_SET_MM_START_STACK = 0x5 -+ PR_SET_NAME = 0xf -+ PR_SET_NO_NEW_PRIVS = 0x26 -+ PR_SET_PDEATHSIG = 0x1 -+ PR_SET_PTRACER = 0x59616d61 -+ PR_SET_PTRACER_ANY = 0xffffffffffffffff -+ PR_SET_SECCOMP = 0x16 -+ PR_SET_SECUREBITS = 0x1c -+ PR_SET_SPECULATION_CTRL = 0x35 -+ PR_SET_THP_DISABLE = 0x29 -+ PR_SET_TIMERSLACK = 0x1d -+ PR_SET_TIMING = 0xe -+ PR_SET_TSC = 0x1a -+ PR_SET_UNALIGN = 0x6 -+ PR_SPEC_DISABLE = 0x4 -+ PR_SPEC_ENABLE = 0x2 -+ PR_SPEC_FORCE_DISABLE = 0x8 -+ PR_SPEC_INDIRECT_BRANCH = 0x1 -+ PR_SPEC_NOT_AFFECTED = 0x0 -+ PR_SPEC_PRCTL = 0x1 -+ PR_SPEC_STORE_BYPASS = 0x0 -+ PR_SVE_GET_VL = 0x33 -+ PR_SVE_SET_VL = 0x32 -+ PR_SVE_SET_VL_ONEXEC = 0x40000 -+ PR_SVE_VL_INHERIT = 0x20000 -+ PR_SVE_VL_LEN_MASK = 0xffff -+ PR_TASK_PERF_EVENTS_DISABLE = 0x1f -+ PR_TASK_PERF_EVENTS_ENABLE = 0x20 -+ PR_TIMING_STATISTICAL = 0x0 -+ PR_TIMING_TIMESTAMP = 0x1 -+ PR_TSC_ENABLE = 0x1 -+ PR_TSC_SIGSEGV = 0x2 -+ PR_UNALIGN_NOPRINT = 0x1 -+ PR_UNALIGN_SIGBUS = 0x2 -+ PSTOREFS_MAGIC = 0x6165676c -+ PTRACE_ATTACH = 0x10 -+ PTRACE_CONT = 0x7 -+ PTRACE_DETACH = 0x11 -+ PTRACE_EVENT_CLONE = 0x3 -+ PTRACE_EVENT_EXEC = 0x4 -+ PTRACE_EVENT_EXIT = 0x6 -+ PTRACE_EVENT_FORK = 0x1 -+ PTRACE_EVENT_SECCOMP = 0x7 -+ PTRACE_EVENT_STOP = 0x80 -+ PTRACE_EVENT_VFORK = 0x2 -+ PTRACE_EVENT_VFORK_DONE = 0x5 -+ PTRACE_GETEVENTMSG = 0x4201 -+ PTRACE_GETREGS = 0xc -+ PTRACE_GETREGSET = 0x4204 -+ PTRACE_GETSIGINFO = 0x4202 -+ PTRACE_GETSIGMASK = 0x420a -+ PTRACE_INTERRUPT = 0x4207 -+ PTRACE_KILL = 0x8 -+ PTRACE_LISTEN = 0x4208 -+ PTRACE_O_EXITKILL = 0x100000 -+ PTRACE_O_MASK = 0x3000ff -+ PTRACE_O_SUSPEND_SECCOMP = 0x200000 -+ PTRACE_O_TRACECLONE = 0x8 -+ PTRACE_O_TRACEEXEC = 0x10 -+ PTRACE_O_TRACEEXIT = 0x40 -+ PTRACE_O_TRACEFORK = 0x2 -+ PTRACE_O_TRACESECCOMP = 0x80 -+ PTRACE_O_TRACESYSGOOD = 0x1 -+ PTRACE_O_TRACEVFORK = 0x4 -+ PTRACE_O_TRACEVFORKDONE = 0x20 -+ PTRACE_PEEKDATA = 0x2 -+ PTRACE_PEEKSIGINFO = 0x4209 -+ PTRACE_PEEKSIGINFO_SHARED = 0x1 -+ PTRACE_PEEKTEXT = 0x1 -+ PTRACE_PEEKUSR = 0x3 -+ PTRACE_POKEDATA = 0x5 -+ PTRACE_POKETEXT = 0x4 -+ PTRACE_POKEUSR = 0x6 -+ PTRACE_SECCOMP_GET_FILTER = 0x420c -+ PTRACE_SECCOMP_GET_METADATA = 0x420d -+ PTRACE_SEIZE = 0x4206 -+ PTRACE_SETOPTIONS = 0x4200 -+ PTRACE_SETREGS = 0xd -+ PTRACE_SETREGSET = 0x4205 -+ PTRACE_SETSIGINFO = 0x4203 -+ PTRACE_SETSIGMASK = 0x420b -+ PTRACE_SINGLESTEP = 0x9 -+ PTRACE_SYSCALL = 0x18 -+ PTRACE_TRACEME = 0x0 -+ QNX4_SUPER_MAGIC = 0x2f -+ QNX6_SUPER_MAGIC = 0x68191122 -+ RAMFS_MAGIC = 0x858458f6 -+ RDTGROUP_SUPER_MAGIC = 0x7655821 -+ REISERFS_SUPER_MAGIC = 0x52654973 -+ RENAME_EXCHANGE = 0x2 -+ RENAME_NOREPLACE = 0x1 -+ RENAME_WHITEOUT = 0x4 -+ RLIMIT_AS = 0x9 -+ RLIMIT_CORE = 0x4 -+ RLIMIT_CPU = 0x0 -+ RLIMIT_DATA = 0x2 -+ RLIMIT_FSIZE = 0x1 -+ RLIMIT_LOCKS = 0xa -+ RLIMIT_MEMLOCK = 0x8 -+ RLIMIT_MSGQUEUE = 0xc -+ RLIMIT_NICE = 0xd -+ RLIMIT_NOFILE = 0x7 -+ RLIMIT_NPROC = 0x6 -+ RLIMIT_RSS = 0x5 -+ RLIMIT_RTPRIO = 0xe -+ RLIMIT_RTTIME = 0xf -+ RLIMIT_SIGPENDING = 0xb -+ RLIMIT_STACK = 0x3 -+ RLIM_INFINITY = 0xffffffffffffffff -+ RNDADDENTROPY = 0x40085203 -+ RNDADDTOENTCNT = 0x40045201 -+ RNDCLEARPOOL = 0x5206 -+ RNDGETENTCNT = 0x80045200 -+ RNDGETPOOL = 0x80085202 -+ RNDRESEEDCRNG = 0x5207 -+ RNDZAPENTCNT = 0x5204 -+ RTAX_ADVMSS = 0x8 -+ RTAX_CC_ALGO = 0x10 -+ RTAX_CWND = 0x7 -+ RTAX_FASTOPEN_NO_COOKIE = 0x11 -+ RTAX_FEATURES = 0xc -+ RTAX_FEATURE_ALLFRAG = 0x8 -+ RTAX_FEATURE_ECN = 0x1 -+ RTAX_FEATURE_MASK = 0xf -+ RTAX_FEATURE_SACK = 0x2 -+ RTAX_FEATURE_TIMESTAMP = 0x4 -+ RTAX_HOPLIMIT = 0xa -+ RTAX_INITCWND = 0xb -+ RTAX_INITRWND = 0xe -+ RTAX_LOCK = 0x1 -+ RTAX_MAX = 0x11 -+ RTAX_MTU = 0x2 -+ RTAX_QUICKACK = 0xf -+ RTAX_REORDERING = 0x9 -+ RTAX_RTO_MIN = 0xd -+ RTAX_RTT = 0x4 -+ RTAX_RTTVAR = 0x5 -+ RTAX_SSTHRESH = 0x6 -+ RTAX_UNSPEC = 0x0 -+ RTAX_WINDOW = 0x3 -+ RTA_ALIGNTO = 0x4 -+ RTA_MAX = 0x1d -+ RTCF_DIRECTSRC = 0x4000000 -+ RTCF_DOREDIRECT = 0x1000000 -+ RTCF_LOG = 0x2000000 -+ RTCF_MASQ = 0x400000 -+ RTCF_NAT = 0x800000 -+ RTCF_VALVE = 0x200000 -+ RTC_AF = 0x20 -+ RTC_AIE_OFF = 0x7002 -+ RTC_AIE_ON = 0x7001 -+ RTC_ALM_READ = 0x80247008 -+ RTC_ALM_SET = 0x40247007 -+ RTC_EPOCH_READ = 0x8008700d -+ RTC_EPOCH_SET = 0x4008700e -+ RTC_IRQF = 0x80 -+ RTC_IRQP_READ = 0x8008700b -+ RTC_IRQP_SET = 0x4008700c -+ RTC_MAX_FREQ = 0x2000 -+ RTC_PF = 0x40 -+ RTC_PIE_OFF = 0x7006 -+ RTC_PIE_ON = 0x7005 -+ RTC_PLL_GET = 0x80207011 -+ RTC_PLL_SET = 0x40207012 -+ RTC_RD_TIME = 0x80247009 -+ RTC_SET_TIME = 0x4024700a -+ RTC_UF = 0x10 -+ RTC_UIE_OFF = 0x7004 -+ RTC_UIE_ON = 0x7003 -+ RTC_VL_CLR = 0x7014 -+ RTC_VL_READ = 0x80047013 -+ RTC_WIE_OFF = 0x7010 -+ RTC_WIE_ON = 0x700f -+ RTC_WKALM_RD = 0x80287010 -+ RTC_WKALM_SET = 0x4028700f -+ RTF_ADDRCLASSMASK = 0xf8000000 -+ RTF_ADDRCONF = 0x40000 -+ RTF_ALLONLINK = 0x20000 -+ RTF_BROADCAST = 0x10000000 -+ RTF_CACHE = 0x1000000 -+ RTF_DEFAULT = 0x10000 -+ RTF_DYNAMIC = 0x10 -+ RTF_FLOW = 0x2000000 -+ RTF_GATEWAY = 0x2 -+ RTF_HOST = 0x4 -+ RTF_INTERFACE = 0x40000000 -+ RTF_IRTT = 0x100 -+ RTF_LINKRT = 0x100000 -+ RTF_LOCAL = 0x80000000 -+ RTF_MODIFIED = 0x20 -+ RTF_MSS = 0x40 -+ RTF_MTU = 0x40 -+ RTF_MULTICAST = 0x20000000 -+ RTF_NAT = 0x8000000 -+ RTF_NOFORWARD = 0x1000 -+ RTF_NONEXTHOP = 0x200000 -+ RTF_NOPMTUDISC = 0x4000 -+ RTF_POLICY = 0x4000000 -+ RTF_REINSTATE = 0x8 -+ RTF_REJECT = 0x200 -+ RTF_STATIC = 0x400 -+ RTF_THROW = 0x2000 -+ RTF_UP = 0x1 -+ RTF_WINDOW = 0x80 -+ RTF_XRESOLVE = 0x800 -+ RTM_BASE = 0x10 -+ RTM_DELACTION = 0x31 -+ RTM_DELADDR = 0x15 -+ RTM_DELADDRLABEL = 0x49 -+ RTM_DELCHAIN = 0x65 -+ RTM_DELLINK = 0x11 -+ RTM_DELMDB = 0x55 -+ RTM_DELNEIGH = 0x1d -+ RTM_DELNETCONF = 0x51 -+ RTM_DELNSID = 0x59 -+ RTM_DELQDISC = 0x25 -+ RTM_DELROUTE = 0x19 -+ RTM_DELRULE = 0x21 -+ RTM_DELTCLASS = 0x29 -+ RTM_DELTFILTER = 0x2d -+ RTM_F_CLONED = 0x200 -+ RTM_F_EQUALIZE = 0x400 -+ RTM_F_FIB_MATCH = 0x2000 -+ RTM_F_LOOKUP_TABLE = 0x1000 -+ RTM_F_NOTIFY = 0x100 -+ RTM_F_PREFIX = 0x800 -+ RTM_GETACTION = 0x32 -+ RTM_GETADDR = 0x16 -+ RTM_GETADDRLABEL = 0x4a -+ RTM_GETANYCAST = 0x3e -+ RTM_GETCHAIN = 0x66 -+ RTM_GETDCB = 0x4e -+ RTM_GETLINK = 0x12 -+ RTM_GETMDB = 0x56 -+ RTM_GETMULTICAST = 0x3a -+ RTM_GETNEIGH = 0x1e -+ RTM_GETNEIGHTBL = 0x42 -+ RTM_GETNETCONF = 0x52 -+ RTM_GETNSID = 0x5a -+ RTM_GETQDISC = 0x26 -+ RTM_GETROUTE = 0x1a -+ RTM_GETRULE = 0x22 -+ RTM_GETSTATS = 0x5e -+ RTM_GETTCLASS = 0x2a -+ RTM_GETTFILTER = 0x2e -+ RTM_MAX = 0x67 -+ RTM_NEWACTION = 0x30 -+ RTM_NEWADDR = 0x14 -+ RTM_NEWADDRLABEL = 0x48 -+ RTM_NEWCACHEREPORT = 0x60 -+ RTM_NEWCHAIN = 0x64 -+ RTM_NEWLINK = 0x10 -+ RTM_NEWMDB = 0x54 -+ RTM_NEWNDUSEROPT = 0x44 -+ RTM_NEWNEIGH = 0x1c -+ RTM_NEWNEIGHTBL = 0x40 -+ RTM_NEWNETCONF = 0x50 -+ RTM_NEWNSID = 0x58 -+ RTM_NEWPREFIX = 0x34 -+ RTM_NEWQDISC = 0x24 -+ RTM_NEWROUTE = 0x18 -+ RTM_NEWRULE = 0x20 -+ RTM_NEWSTATS = 0x5c -+ RTM_NEWTCLASS = 0x28 -+ RTM_NEWTFILTER = 0x2c -+ RTM_NR_FAMILIES = 0x16 -+ RTM_NR_MSGTYPES = 0x58 -+ RTM_SETDCB = 0x4f -+ RTM_SETLINK = 0x13 -+ RTM_SETNEIGHTBL = 0x43 -+ RTNH_ALIGNTO = 0x4 -+ RTNH_COMPARE_MASK = 0x19 -+ RTNH_F_DEAD = 0x1 -+ RTNH_F_LINKDOWN = 0x10 -+ RTNH_F_OFFLOAD = 0x8 -+ RTNH_F_ONLINK = 0x4 -+ RTNH_F_PERVASIVE = 0x2 -+ RTNH_F_UNRESOLVED = 0x20 -+ RTN_MAX = 0xb -+ RTPROT_BABEL = 0x2a -+ RTPROT_BGP = 0xba -+ RTPROT_BIRD = 0xc -+ RTPROT_BOOT = 0x3 -+ RTPROT_DHCP = 0x10 -+ RTPROT_DNROUTED = 0xd -+ RTPROT_EIGRP = 0xc0 -+ RTPROT_GATED = 0x8 -+ RTPROT_ISIS = 0xbb -+ RTPROT_KERNEL = 0x2 -+ RTPROT_MROUTED = 0x11 -+ RTPROT_MRT = 0xa -+ RTPROT_NTK = 0xf -+ RTPROT_OSPF = 0xbc -+ RTPROT_RA = 0x9 -+ RTPROT_REDIRECT = 0x1 -+ RTPROT_RIP = 0xbd -+ RTPROT_STATIC = 0x4 -+ RTPROT_UNSPEC = 0x0 -+ RTPROT_XORP = 0xe -+ RTPROT_ZEBRA = 0xb -+ RT_CLASS_DEFAULT = 0xfd -+ RT_CLASS_LOCAL = 0xff -+ RT_CLASS_MAIN = 0xfe -+ RT_CLASS_MAX = 0xff -+ RT_CLASS_UNSPEC = 0x0 -+ RUSAGE_CHILDREN = -0x1 -+ RUSAGE_SELF = 0x0 -+ RUSAGE_THREAD = 0x1 -+ SCM_CREDENTIALS = 0x2 -+ SCM_RIGHTS = 0x1 -+ SCM_TIMESTAMP = 0x1d -+ SCM_TIMESTAMPING = 0x25 -+ SCM_TIMESTAMPING_OPT_STATS = 0x36 -+ SCM_TIMESTAMPING_PKTINFO = 0x3a -+ SCM_TIMESTAMPNS = 0x23 -+ SCM_TXTIME = 0x3d -+ SCM_WIFI_STATUS = 0x29 -+ SC_LOG_FLUSH = 0x100000 -+ SECCOMP_MODE_DISABLED = 0x0 -+ SECCOMP_MODE_FILTER = 0x2 -+ SECCOMP_MODE_STRICT = 0x1 -+ SECURITYFS_MAGIC = 0x73636673 -+ SELINUX_MAGIC = 0xf97cff8c -+ SFD_CLOEXEC = 0x80000 -+ SFD_NONBLOCK = 0x800 -+ SHUT_RD = 0x0 -+ SHUT_RDWR = 0x2 -+ SHUT_WR = 0x1 -+ SIOCADDDLCI = 0x8980 -+ SIOCADDMULTI = 0x8931 -+ SIOCADDRT = 0x890b -+ SIOCATMARK = 0x8905 -+ SIOCBONDCHANGEACTIVE = 0x8995 -+ SIOCBONDENSLAVE = 0x8990 -+ SIOCBONDINFOQUERY = 0x8994 -+ SIOCBONDRELEASE = 0x8991 -+ SIOCBONDSETHWADDR = 0x8992 -+ SIOCBONDSLAVEINFOQUERY = 0x8993 -+ SIOCBRADDBR = 0x89a0 -+ SIOCBRADDIF = 0x89a2 -+ SIOCBRDELBR = 0x89a1 -+ SIOCBRDELIF = 0x89a3 -+ SIOCDARP = 0x8953 -+ SIOCDELDLCI = 0x8981 -+ SIOCDELMULTI = 0x8932 -+ SIOCDELRT = 0x890c -+ SIOCDEVPRIVATE = 0x89f0 -+ SIOCDIFADDR = 0x8936 -+ SIOCDRARP = 0x8960 -+ SIOCETHTOOL = 0x8946 -+ SIOCGARP = 0x8954 -+ SIOCGHWTSTAMP = 0x89b1 -+ SIOCGIFADDR = 0x8915 -+ SIOCGIFBR = 0x8940 -+ SIOCGIFBRDADDR = 0x8919 -+ SIOCGIFCONF = 0x8912 -+ SIOCGIFCOUNT = 0x8938 -+ SIOCGIFDSTADDR = 0x8917 -+ SIOCGIFENCAP = 0x8925 -+ SIOCGIFFLAGS = 0x8913 -+ SIOCGIFHWADDR = 0x8927 -+ SIOCGIFINDEX = 0x8933 -+ SIOCGIFMAP = 0x8970 -+ SIOCGIFMEM = 0x891f -+ SIOCGIFMETRIC = 0x891d -+ SIOCGIFMTU = 0x8921 -+ SIOCGIFNAME = 0x8910 -+ SIOCGIFNETMASK = 0x891b -+ SIOCGIFPFLAGS = 0x8935 -+ SIOCGIFSLAVE = 0x8929 -+ SIOCGIFTXQLEN = 0x8942 -+ SIOCGIFVLAN = 0x8982 -+ SIOCGMIIPHY = 0x8947 -+ SIOCGMIIREG = 0x8948 -+ SIOCGPGRP = 0x8904 -+ SIOCGPPPCSTATS = 0x89f2 -+ SIOCGPPPSTATS = 0x89f0 -+ SIOCGPPPVER = 0x89f1 -+ SIOCGRARP = 0x8961 -+ SIOCGSKNS = 0x894c -+ SIOCGSTAMP = 0x8906 -+ SIOCGSTAMPNS = 0x8907 -+ SIOCINQ = 0x541b -+ SIOCOUTQ = 0x5411 -+ SIOCOUTQNSD = 0x894b -+ SIOCPROTOPRIVATE = 0x89e0 -+ SIOCRTMSG = 0x890d -+ SIOCSARP = 0x8955 -+ SIOCSHWTSTAMP = 0x89b0 -+ SIOCSIFADDR = 0x8916 -+ SIOCSIFBR = 0x8941 -+ SIOCSIFBRDADDR = 0x891a -+ SIOCSIFDSTADDR = 0x8918 -+ SIOCSIFENCAP = 0x8926 -+ SIOCSIFFLAGS = 0x8914 -+ SIOCSIFHWADDR = 0x8924 -+ SIOCSIFHWBROADCAST = 0x8937 -+ SIOCSIFLINK = 0x8911 -+ SIOCSIFMAP = 0x8971 -+ SIOCSIFMEM = 0x8920 -+ SIOCSIFMETRIC = 0x891e -+ SIOCSIFMTU = 0x8922 -+ SIOCSIFNAME = 0x8923 -+ SIOCSIFNETMASK = 0x891c -+ SIOCSIFPFLAGS = 0x8934 -+ SIOCSIFSLAVE = 0x8930 -+ SIOCSIFTXQLEN = 0x8943 -+ SIOCSIFVLAN = 0x8983 -+ SIOCSMIIREG = 0x8949 -+ SIOCSPGRP = 0x8902 -+ SIOCSRARP = 0x8962 -+ SIOCWANDEV = 0x894a -+ SMACK_MAGIC = 0x43415d53 -+ SMART_AUTOSAVE = 0xd2 -+ SMART_AUTO_OFFLINE = 0xdb -+ SMART_DISABLE = 0xd9 -+ SMART_ENABLE = 0xd8 -+ SMART_HCYL_PASS = 0xc2 -+ SMART_IMMEDIATE_OFFLINE = 0xd4 -+ SMART_LCYL_PASS = 0x4f -+ SMART_READ_LOG_SECTOR = 0xd5 -+ SMART_READ_THRESHOLDS = 0xd1 -+ SMART_READ_VALUES = 0xd0 -+ SMART_SAVE = 0xd3 -+ SMART_STATUS = 0xda -+ SMART_WRITE_LOG_SECTOR = 0xd6 -+ SMART_WRITE_THRESHOLDS = 0xd7 -+ SMB_SUPER_MAGIC = 0x517b -+ SOCKFS_MAGIC = 0x534f434b -+ SOCK_CLOEXEC = 0x80000 -+ SOCK_DCCP = 0x6 -+ SOCK_DGRAM = 0x2 -+ SOCK_IOC_TYPE = 0x89 -+ SOCK_NONBLOCK = 0x800 -+ SOCK_PACKET = 0xa -+ SOCK_RAW = 0x3 -+ SOCK_RDM = 0x4 -+ SOCK_SEQPACKET = 0x5 -+ SOCK_STREAM = 0x1 -+ SOL_AAL = 0x109 -+ SOL_ALG = 0x117 -+ SOL_ATM = 0x108 -+ SOL_CAIF = 0x116 -+ SOL_CAN_BASE = 0x64 -+ SOL_DCCP = 0x10d -+ SOL_DECNET = 0x105 -+ SOL_ICMPV6 = 0x3a -+ SOL_IP = 0x0 -+ SOL_IPV6 = 0x29 -+ SOL_IRDA = 0x10a -+ SOL_IUCV = 0x115 -+ SOL_KCM = 0x119 -+ SOL_LLC = 0x10c -+ SOL_NETBEUI = 0x10b -+ SOL_NETLINK = 0x10e -+ SOL_NFC = 0x118 -+ SOL_PACKET = 0x107 -+ SOL_PNPIPE = 0x113 -+ SOL_PPPOL2TP = 0x111 -+ SOL_RAW = 0xff -+ SOL_RDS = 0x114 -+ SOL_RXRPC = 0x110 -+ SOL_SOCKET = 0x1 -+ SOL_TCP = 0x6 -+ SOL_TIPC = 0x10f -+ SOL_TLS = 0x11a -+ SOL_X25 = 0x106 -+ SOL_XDP = 0x11b -+ SOMAXCONN = 0x80 -+ SO_ACCEPTCONN = 0x1e -+ SO_ATTACH_BPF = 0x32 -+ SO_ATTACH_FILTER = 0x1a -+ SO_ATTACH_REUSEPORT_CBPF = 0x33 -+ SO_ATTACH_REUSEPORT_EBPF = 0x34 -+ SO_BINDTODEVICE = 0x19 -+ SO_BPF_EXTENSIONS = 0x30 -+ SO_BROADCAST = 0x6 -+ SO_BSDCOMPAT = 0xe -+ SO_BUSY_POLL = 0x2e -+ SO_CNX_ADVICE = 0x35 -+ SO_COOKIE = 0x39 -+ SO_DEBUG = 0x1 -+ SO_DETACH_BPF = 0x1b -+ SO_DETACH_FILTER = 0x1b -+ SO_DOMAIN = 0x27 -+ SO_DONTROUTE = 0x5 -+ SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 -+ SO_EE_CODE_TXTIME_MISSED = 0x2 -+ SO_EE_CODE_ZEROCOPY_COPIED = 0x1 -+ SO_EE_ORIGIN_ICMP = 0x2 -+ SO_EE_ORIGIN_ICMP6 = 0x3 -+ SO_EE_ORIGIN_LOCAL = 0x1 -+ SO_EE_ORIGIN_NONE = 0x0 -+ SO_EE_ORIGIN_TIMESTAMPING = 0x4 -+ SO_EE_ORIGIN_TXSTATUS = 0x4 -+ SO_EE_ORIGIN_TXTIME = 0x6 -+ SO_EE_ORIGIN_ZEROCOPY = 0x5 -+ SO_ERROR = 0x4 -+ SO_GET_FILTER = 0x1a -+ SO_INCOMING_CPU = 0x31 -+ SO_INCOMING_NAPI_ID = 0x38 -+ SO_KEEPALIVE = 0x9 -+ SO_LINGER = 0xd -+ SO_LOCK_FILTER = 0x2c -+ SO_MARK = 0x24 -+ SO_MAX_PACING_RATE = 0x2f -+ SO_MEMINFO = 0x37 -+ SO_NOFCS = 0x2b -+ SO_NO_CHECK = 0xb -+ SO_OOBINLINE = 0xa -+ SO_PASSCRED = 0x10 -+ SO_PASSSEC = 0x22 -+ SO_PEEK_OFF = 0x2a -+ SO_PEERCRED = 0x11 -+ SO_PEERGROUPS = 0x3b -+ SO_PEERNAME = 0x1c -+ SO_PEERSEC = 0x1f -+ SO_PRIORITY = 0xc -+ SO_PROTOCOL = 0x26 -+ SO_RCVBUF = 0x8 -+ SO_RCVBUFFORCE = 0x21 -+ SO_RCVLOWAT = 0x12 -+ SO_RCVTIMEO = 0x14 -+ SO_REUSEADDR = 0x2 -+ SO_REUSEPORT = 0xf -+ SO_RXQ_OVFL = 0x28 -+ SO_SECURITY_AUTHENTICATION = 0x16 -+ SO_SECURITY_ENCRYPTION_NETWORK = 0x18 -+ SO_SECURITY_ENCRYPTION_TRANSPORT = 0x17 -+ SO_SELECT_ERR_QUEUE = 0x2d -+ SO_SNDBUF = 0x7 -+ SO_SNDBUFFORCE = 0x20 -+ SO_SNDLOWAT = 0x13 -+ SO_SNDTIMEO = 0x15 -+ SO_TIMESTAMP = 0x1d -+ SO_TIMESTAMPING = 0x25 -+ SO_TIMESTAMPNS = 0x23 -+ SO_TXTIME = 0x3d -+ SO_TYPE = 0x3 -+ SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2 -+ SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1 -+ SO_VM_SOCKETS_BUFFER_SIZE = 0x0 -+ SO_VM_SOCKETS_CONNECT_TIMEOUT = 0x6 -+ SO_VM_SOCKETS_NONBLOCK_TXRX = 0x7 -+ SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 -+ SO_VM_SOCKETS_TRUSTED = 0x5 -+ SO_WIFI_STATUS = 0x29 -+ SO_ZEROCOPY = 0x3c -+ SPLICE_F_GIFT = 0x8 -+ SPLICE_F_MORE = 0x4 -+ SPLICE_F_MOVE = 0x1 -+ SPLICE_F_NONBLOCK = 0x2 -+ SQUASHFS_MAGIC = 0x73717368 -+ STACK_END_MAGIC = 0x57ac6e9d -+ STATX_ALL = 0xfff -+ STATX_ATIME = 0x20 -+ STATX_ATTR_APPEND = 0x20 -+ STATX_ATTR_AUTOMOUNT = 0x1000 -+ STATX_ATTR_COMPRESSED = 0x4 -+ STATX_ATTR_ENCRYPTED = 0x800 -+ STATX_ATTR_IMMUTABLE = 0x10 -+ STATX_ATTR_NODUMP = 0x40 -+ STATX_BASIC_STATS = 0x7ff -+ STATX_BLOCKS = 0x400 -+ STATX_BTIME = 0x800 -+ STATX_CTIME = 0x80 -+ STATX_GID = 0x10 -+ STATX_INO = 0x100 -+ STATX_MODE = 0x2 -+ STATX_MTIME = 0x40 -+ STATX_NLINK = 0x4 -+ STATX_SIZE = 0x200 -+ STATX_TYPE = 0x1 -+ STATX_UID = 0x8 -+ STATX__RESERVED = 0x80000000 -+ SYNC_FILE_RANGE_WAIT_AFTER = 0x4 -+ SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 -+ SYNC_FILE_RANGE_WRITE = 0x2 -+ SYSFS_MAGIC = 0x62656572 -+ S_BLKSIZE = 0x200 -+ S_IEXEC = 0x40 -+ S_IFBLK = 0x6000 -+ S_IFCHR = 0x2000 -+ S_IFDIR = 0x4000 -+ S_IFIFO = 0x1000 -+ S_IFLNK = 0xa000 -+ S_IFMT = 0xf000 -+ S_IFREG = 0x8000 -+ S_IFSOCK = 0xc000 -+ S_IREAD = 0x100 -+ S_IRGRP = 0x20 -+ S_IROTH = 0x4 -+ S_IRUSR = 0x100 -+ S_IRWXG = 0x38 -+ S_IRWXO = 0x7 -+ S_IRWXU = 0x1c0 -+ S_ISGID = 0x400 -+ S_ISUID = 0x800 -+ S_ISVTX = 0x200 -+ S_IWGRP = 0x10 -+ S_IWOTH = 0x2 -+ S_IWRITE = 0x80 -+ S_IWUSR = 0x80 -+ S_IXGRP = 0x8 -+ S_IXOTH = 0x1 -+ S_IXUSR = 0x40 -+ TAB0 = 0x0 -+ TAB1 = 0x800 -+ TAB2 = 0x1000 -+ TAB3 = 0x1800 -+ TABDLY = 0x1800 -+ TASKSTATS_CMD_ATTR_MAX = 0x4 -+ TASKSTATS_CMD_MAX = 0x2 -+ TASKSTATS_GENL_NAME = "TASKSTATS" -+ TASKSTATS_GENL_VERSION = 0x1 -+ TASKSTATS_TYPE_MAX = 0x6 -+ TASKSTATS_VERSION = 0x9 -+ TCFLSH = 0x540b -+ TCGETA = 0x5405 -+ TCGETS = 0x5401 -+ TCGETS2 = 0x802c542a -+ TCGETX = 0x5432 -+ TCIFLUSH = 0x0 -+ TCIOFF = 0x2 -+ TCIOFLUSH = 0x2 -+ TCION = 0x3 -+ TCOFLUSH = 0x1 -+ TCOOFF = 0x0 -+ TCOON = 0x1 -+ TCP_CC_INFO = 0x1a -+ TCP_CM_INQ = 0x24 -+ TCP_CONGESTION = 0xd -+ TCP_COOKIE_IN_ALWAYS = 0x1 -+ TCP_COOKIE_MAX = 0x10 -+ TCP_COOKIE_MIN = 0x8 -+ TCP_COOKIE_OUT_NEVER = 0x2 -+ TCP_COOKIE_PAIR_SIZE = 0x20 -+ TCP_COOKIE_TRANSACTIONS = 0xf -+ TCP_CORK = 0x3 -+ TCP_DEFER_ACCEPT = 0x9 -+ TCP_FASTOPEN = 0x17 -+ TCP_FASTOPEN_CONNECT = 0x1e -+ TCP_FASTOPEN_KEY = 0x21 -+ TCP_FASTOPEN_NO_COOKIE = 0x22 -+ TCP_INFO = 0xb -+ TCP_INQ = 0x24 -+ TCP_KEEPCNT = 0x6 -+ TCP_KEEPIDLE = 0x4 -+ TCP_KEEPINTVL = 0x5 -+ TCP_LINGER2 = 0x8 -+ TCP_MAXSEG = 0x2 -+ TCP_MAXWIN = 0xffff -+ TCP_MAX_WINSHIFT = 0xe -+ TCP_MD5SIG = 0xe -+ TCP_MD5SIG_EXT = 0x20 -+ TCP_MD5SIG_FLAG_PREFIX = 0x1 -+ TCP_MD5SIG_MAXKEYLEN = 0x50 -+ TCP_MSS = 0x200 -+ TCP_MSS_DEFAULT = 0x218 -+ TCP_MSS_DESIRED = 0x4c4 -+ TCP_NODELAY = 0x1 -+ TCP_NOTSENT_LOWAT = 0x19 -+ TCP_QUEUE_SEQ = 0x15 -+ TCP_QUICKACK = 0xc -+ TCP_REPAIR = 0x13 -+ TCP_REPAIR_OFF = 0x0 -+ TCP_REPAIR_OFF_NO_WP = -0x1 -+ TCP_REPAIR_ON = 0x1 -+ TCP_REPAIR_OPTIONS = 0x16 -+ TCP_REPAIR_QUEUE = 0x14 -+ TCP_REPAIR_WINDOW = 0x1d -+ TCP_SAVED_SYN = 0x1c -+ TCP_SAVE_SYN = 0x1b -+ TCP_SYNCNT = 0x7 -+ TCP_S_DATA_IN = 0x4 -+ TCP_S_DATA_OUT = 0x8 -+ TCP_THIN_DUPACK = 0x11 -+ TCP_THIN_LINEAR_TIMEOUTS = 0x10 -+ TCP_TIMESTAMP = 0x18 -+ TCP_ULP = 0x1f -+ TCP_USER_TIMEOUT = 0x12 -+ TCP_WINDOW_CLAMP = 0xa -+ TCP_ZEROCOPY_RECEIVE = 0x23 -+ TCSAFLUSH = 0x2 -+ TCSBRK = 0x5409 -+ TCSBRKP = 0x5425 -+ TCSETA = 0x5406 -+ TCSETAF = 0x5408 -+ TCSETAW = 0x5407 -+ TCSETS = 0x5402 -+ TCSETS2 = 0x402c542b -+ TCSETSF = 0x5404 -+ TCSETSF2 = 0x402c542d -+ TCSETSW = 0x5403 -+ TCSETSW2 = 0x402c542c -+ TCSETX = 0x5433 -+ TCSETXF = 0x5434 -+ TCSETXW = 0x5435 -+ TCXONC = 0x540a -+ TIMER_ABSTIME = 0x1 -+ TIOCCBRK = 0x5428 -+ TIOCCONS = 0x541d -+ TIOCEXCL = 0x540c -+ TIOCGDEV = 0x80045432 -+ TIOCGETD = 0x5424 -+ TIOCGEXCL = 0x80045440 -+ TIOCGICOUNT = 0x545d -+ TIOCGISO7816 = 0x80285442 -+ TIOCGLCKTRMIOS = 0x5456 -+ TIOCGPGRP = 0x540f -+ TIOCGPKT = 0x80045438 -+ TIOCGPTLCK = 0x80045439 -+ TIOCGPTN = 0x80045430 -+ TIOCGPTPEER = 0x5441 -+ TIOCGRS485 = 0x542e -+ TIOCGSERIAL = 0x541e -+ TIOCGSID = 0x5429 -+ TIOCGSOFTCAR = 0x5419 -+ TIOCGWINSZ = 0x5413 -+ TIOCINQ = 0x541b -+ TIOCLINUX = 0x541c -+ TIOCMBIC = 0x5417 -+ TIOCMBIS = 0x5416 -+ TIOCMGET = 0x5415 -+ TIOCMIWAIT = 0x545c -+ TIOCMSET = 0x5418 -+ TIOCM_CAR = 0x40 -+ TIOCM_CD = 0x40 -+ TIOCM_CTS = 0x20 -+ TIOCM_DSR = 0x100 -+ TIOCM_DTR = 0x2 -+ TIOCM_LE = 0x1 -+ TIOCM_RI = 0x80 -+ TIOCM_RNG = 0x80 -+ TIOCM_RTS = 0x4 -+ TIOCM_SR = 0x10 -+ TIOCM_ST = 0x8 -+ TIOCNOTTY = 0x5422 -+ TIOCNXCL = 0x540d -+ TIOCOUTQ = 0x5411 -+ TIOCPKT = 0x5420 -+ TIOCPKT_DATA = 0x0 -+ TIOCPKT_DOSTOP = 0x20 -+ TIOCPKT_FLUSHREAD = 0x1 -+ TIOCPKT_FLUSHWRITE = 0x2 -+ TIOCPKT_IOCTL = 0x40 -+ TIOCPKT_NOSTOP = 0x10 -+ TIOCPKT_START = 0x8 -+ TIOCPKT_STOP = 0x4 -+ TIOCSBRK = 0x5427 -+ TIOCSCTTY = 0x540e -+ TIOCSERCONFIG = 0x5453 -+ TIOCSERGETLSR = 0x5459 -+ TIOCSERGETMULTI = 0x545a -+ TIOCSERGSTRUCT = 0x5458 -+ TIOCSERGWILD = 0x5454 -+ TIOCSERSETMULTI = 0x545b -+ TIOCSERSWILD = 0x5455 -+ TIOCSER_TEMT = 0x1 -+ TIOCSETD = 0x5423 -+ TIOCSIG = 0x40045436 -+ TIOCSISO7816 = 0xc0285443 -+ TIOCSLCKTRMIOS = 0x5457 -+ TIOCSPGRP = 0x5410 -+ TIOCSPTLCK = 0x40045431 -+ TIOCSRS485 = 0x542f -+ TIOCSSERIAL = 0x541f -+ TIOCSSOFTCAR = 0x541a -+ TIOCSTI = 0x5412 -+ TIOCSWINSZ = 0x5414 -+ TIOCVHANGUP = 0x5437 -+ TMPFS_MAGIC = 0x1021994 -+ TOSTOP = 0x100 -+ TPACKET_ALIGNMENT = 0x10 -+ TPACKET_HDRLEN = 0x34 -+ TP_STATUS_AVAILABLE = 0x0 -+ TP_STATUS_BLK_TMO = 0x20 -+ TP_STATUS_COPY = 0x2 -+ TP_STATUS_CSUMNOTREADY = 0x8 -+ TP_STATUS_CSUM_VALID = 0x80 -+ TP_STATUS_KERNEL = 0x0 -+ TP_STATUS_LOSING = 0x4 -+ TP_STATUS_SENDING = 0x2 -+ TP_STATUS_SEND_REQUEST = 0x1 -+ TP_STATUS_TS_RAW_HARDWARE = -0x80000000 -+ TP_STATUS_TS_SOFTWARE = 0x20000000 -+ TP_STATUS_TS_SYS_HARDWARE = 0x40000000 -+ TP_STATUS_USER = 0x1 -+ TP_STATUS_VLAN_TPID_VALID = 0x40 -+ TP_STATUS_VLAN_VALID = 0x10 -+ TP_STATUS_WRONG_FORMAT = 0x4 -+ TRACEFS_MAGIC = 0x74726163 -+ TS_COMM_LEN = 0x20 -+ TUNATTACHFILTER = 0x401054d5 -+ TUNDETACHFILTER = 0x401054d6 -+ TUNGETFEATURES = 0x800454cf -+ TUNGETFILTER = 0x801054db -+ TUNGETIFF = 0x800454d2 -+ TUNGETSNDBUF = 0x800454d3 -+ TUNGETVNETBE = 0x800454df -+ TUNGETVNETHDRSZ = 0x800454d7 -+ TUNGETVNETLE = 0x800454dd -+ TUNSETDEBUG = 0x400454c9 -+ TUNSETFILTEREBPF = 0x800454e1 -+ TUNSETGROUP = 0x400454ce -+ TUNSETIFF = 0x400454ca -+ TUNSETIFINDEX = 0x400454da -+ TUNSETLINK = 0x400454cd -+ TUNSETNOCSUM = 0x400454c8 -+ TUNSETOFFLOAD = 0x400454d0 -+ TUNSETOWNER = 0x400454cc -+ TUNSETPERSIST = 0x400454cb -+ TUNSETQUEUE = 0x400454d9 -+ TUNSETSNDBUF = 0x400454d4 -+ TUNSETSTEERINGEBPF = 0x800454e0 -+ TUNSETTXFILTER = 0x400454d1 -+ TUNSETVNETBE = 0x400454de -+ TUNSETVNETHDRSZ = 0x400454d8 -+ TUNSETVNETLE = 0x400454dc -+ UBI_IOCATT = 0x40186f40 -+ UBI_IOCDET = 0x40046f41 -+ UBI_IOCEBCH = 0x40044f02 -+ UBI_IOCEBER = 0x40044f01 -+ UBI_IOCEBISMAP = 0x80044f05 -+ UBI_IOCEBMAP = 0x40084f03 -+ UBI_IOCEBUNMAP = 0x40044f04 -+ UBI_IOCMKVOL = 0x40986f00 -+ UBI_IOCRMVOL = 0x40046f01 -+ UBI_IOCRNVOL = 0x51106f03 -+ UBI_IOCRSVOL = 0x400c6f02 -+ UBI_IOCSETVOLPROP = 0x40104f06 -+ UBI_IOCVOLCRBLK = 0x40804f07 -+ UBI_IOCVOLRMBLK = 0x4f08 -+ UBI_IOCVOLUP = 0x40084f00 -+ UDF_SUPER_MAGIC = 0x15013346 -+ UMOUNT_NOFOLLOW = 0x8 -+ USBDEVICE_SUPER_MAGIC = 0x9fa2 -+ UTIME_NOW = 0x3fffffff -+ UTIME_OMIT = 0x3ffffffe -+ V9FS_MAGIC = 0x1021997 -+ VDISCARD = 0xd -+ VEOF = 0x4 -+ VEOL = 0xb -+ VEOL2 = 0x10 -+ VERASE = 0x2 -+ VINTR = 0x0 -+ VKILL = 0x3 -+ VLNEXT = 0xf -+ VMADDR_CID_ANY = 0xffffffff -+ VMADDR_CID_HOST = 0x2 -+ VMADDR_CID_HYPERVISOR = 0x0 -+ VMADDR_CID_RESERVED = 0x1 -+ VMADDR_PORT_ANY = 0xffffffff -+ VMIN = 0x6 -+ VM_SOCKETS_INVALID_VERSION = 0xffffffff -+ VQUIT = 0x1 -+ VREPRINT = 0xc -+ VSTART = 0x8 -+ VSTOP = 0x9 -+ VSUSP = 0xa -+ VSWTC = 0x7 -+ VT0 = 0x0 -+ VT1 = 0x4000 -+ VTDLY = 0x4000 -+ VTIME = 0x5 -+ VWERASE = 0xe -+ WALL = 0x40000000 -+ WCLONE = 0x80000000 -+ WCONTINUED = 0x8 -+ WDIOC_GETBOOTSTATUS = 0x80045702 -+ WDIOC_GETPRETIMEOUT = 0x80045709 -+ WDIOC_GETSTATUS = 0x80045701 -+ WDIOC_GETSUPPORT = 0x80285700 -+ WDIOC_GETTEMP = 0x80045703 -+ WDIOC_GETTIMELEFT = 0x8004570a -+ WDIOC_GETTIMEOUT = 0x80045707 -+ WDIOC_KEEPALIVE = 0x80045705 -+ WDIOC_SETOPTIONS = 0x80045704 -+ WDIOC_SETPRETIMEOUT = 0xc0045708 -+ WDIOC_SETTIMEOUT = 0xc0045706 -+ WEXITED = 0x4 -+ WIN_ACKMEDIACHANGE = 0xdb -+ WIN_CHECKPOWERMODE1 = 0xe5 -+ WIN_CHECKPOWERMODE2 = 0x98 -+ WIN_DEVICE_RESET = 0x8 -+ WIN_DIAGNOSE = 0x90 -+ WIN_DOORLOCK = 0xde -+ WIN_DOORUNLOCK = 0xdf -+ WIN_DOWNLOAD_MICROCODE = 0x92 -+ WIN_FLUSH_CACHE = 0xe7 -+ WIN_FLUSH_CACHE_EXT = 0xea -+ WIN_FORMAT = 0x50 -+ WIN_GETMEDIASTATUS = 0xda -+ WIN_IDENTIFY = 0xec -+ WIN_IDENTIFY_DMA = 0xee -+ WIN_IDLEIMMEDIATE = 0xe1 -+ WIN_INIT = 0x60 -+ WIN_MEDIAEJECT = 0xed -+ WIN_MULTREAD = 0xc4 -+ WIN_MULTREAD_EXT = 0x29 -+ WIN_MULTWRITE = 0xc5 -+ WIN_MULTWRITE_EXT = 0x39 -+ WIN_NOP = 0x0 -+ WIN_PACKETCMD = 0xa0 -+ WIN_PIDENTIFY = 0xa1 -+ WIN_POSTBOOT = 0xdc -+ WIN_PREBOOT = 0xdd -+ WIN_QUEUED_SERVICE = 0xa2 -+ WIN_READ = 0x20 -+ WIN_READDMA = 0xc8 -+ WIN_READDMA_EXT = 0x25 -+ WIN_READDMA_ONCE = 0xc9 -+ WIN_READDMA_QUEUED = 0xc7 -+ WIN_READDMA_QUEUED_EXT = 0x26 -+ WIN_READ_BUFFER = 0xe4 -+ WIN_READ_EXT = 0x24 -+ WIN_READ_LONG = 0x22 -+ WIN_READ_LONG_ONCE = 0x23 -+ WIN_READ_NATIVE_MAX = 0xf8 -+ WIN_READ_NATIVE_MAX_EXT = 0x27 -+ WIN_READ_ONCE = 0x21 -+ WIN_RECAL = 0x10 -+ WIN_RESTORE = 0x10 -+ WIN_SECURITY_DISABLE = 0xf6 -+ WIN_SECURITY_ERASE_PREPARE = 0xf3 -+ WIN_SECURITY_ERASE_UNIT = 0xf4 -+ WIN_SECURITY_FREEZE_LOCK = 0xf5 -+ WIN_SECURITY_SET_PASS = 0xf1 -+ WIN_SECURITY_UNLOCK = 0xf2 -+ WIN_SEEK = 0x70 -+ WIN_SETFEATURES = 0xef -+ WIN_SETIDLE1 = 0xe3 -+ WIN_SETIDLE2 = 0x97 -+ WIN_SETMULT = 0xc6 -+ WIN_SET_MAX = 0xf9 -+ WIN_SET_MAX_EXT = 0x37 -+ WIN_SLEEPNOW1 = 0xe6 -+ WIN_SLEEPNOW2 = 0x99 -+ WIN_SMART = 0xb0 -+ WIN_SPECIFY = 0x91 -+ WIN_SRST = 0x8 -+ WIN_STANDBY = 0xe2 -+ WIN_STANDBY2 = 0x96 -+ WIN_STANDBYNOW1 = 0xe0 -+ WIN_STANDBYNOW2 = 0x94 -+ WIN_VERIFY = 0x40 -+ WIN_VERIFY_EXT = 0x42 -+ WIN_VERIFY_ONCE = 0x41 -+ WIN_WRITE = 0x30 -+ WIN_WRITEDMA = 0xca -+ WIN_WRITEDMA_EXT = 0x35 -+ WIN_WRITEDMA_ONCE = 0xcb -+ WIN_WRITEDMA_QUEUED = 0xcc -+ WIN_WRITEDMA_QUEUED_EXT = 0x36 -+ WIN_WRITE_BUFFER = 0xe8 -+ WIN_WRITE_EXT = 0x34 -+ WIN_WRITE_LONG = 0x32 -+ WIN_WRITE_LONG_ONCE = 0x33 -+ WIN_WRITE_ONCE = 0x31 -+ WIN_WRITE_SAME = 0xe9 -+ WIN_WRITE_VERIFY = 0x3c -+ WNOHANG = 0x1 -+ WNOTHREAD = 0x20000000 -+ WNOWAIT = 0x1000000 -+ WORDSIZE = 0x40 -+ WSTOPPED = 0x2 -+ WUNTRACED = 0x2 -+ XATTR_CREATE = 0x1 -+ XATTR_REPLACE = 0x2 -+ XCASE = 0x4 -+ XDP_COPY = 0x2 -+ XDP_FLAGS_DRV_MODE = 0x4 -+ XDP_FLAGS_HW_MODE = 0x8 -+ XDP_FLAGS_MASK = 0xf -+ XDP_FLAGS_MODES = 0xe -+ XDP_FLAGS_SKB_MODE = 0x2 -+ XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1 -+ XDP_MMAP_OFFSETS = 0x1 -+ XDP_PGOFF_RX_RING = 0x0 -+ XDP_PGOFF_TX_RING = 0x80000000 -+ XDP_RX_RING = 0x2 -+ XDP_SHARED_UMEM = 0x1 -+ XDP_STATISTICS = 0x7 -+ XDP_TX_RING = 0x3 -+ XDP_UMEM_COMPLETION_RING = 0x6 -+ XDP_UMEM_FILL_RING = 0x5 -+ XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000 -+ XDP_UMEM_PGOFF_FILL_RING = 0x100000000 -+ XDP_UMEM_REG = 0x4 -+ XDP_ZEROCOPY = 0x4 -+ XENFS_SUPER_MAGIC = 0xabba1974 -+ XFS_SUPER_MAGIC = 0x58465342 -+ XTABS = 0x1800 -+ ZSMALLOC_MAGIC = 0x58295829 -+) -+ -+// Errors -+const ( -+ E2BIG = syscall.Errno(0x7) -+ EACCES = syscall.Errno(0xd) -+ EADDRINUSE = syscall.Errno(0x62) -+ EADDRNOTAVAIL = syscall.Errno(0x63) -+ EADV = syscall.Errno(0x44) -+ EAFNOSUPPORT = syscall.Errno(0x61) -+ EAGAIN = syscall.Errno(0xb) -+ EALREADY = syscall.Errno(0x72) -+ EBADE = syscall.Errno(0x34) -+ EBADF = syscall.Errno(0x9) -+ EBADFD = syscall.Errno(0x4d) -+ EBADMSG = syscall.Errno(0x4a) -+ EBADR = syscall.Errno(0x35) -+ EBADRQC = syscall.Errno(0x38) -+ EBADSLT = syscall.Errno(0x39) -+ EBFONT = syscall.Errno(0x3b) -+ EBUSY = syscall.Errno(0x10) -+ ECANCELED = syscall.Errno(0x7d) -+ ECHILD = syscall.Errno(0xa) -+ ECHRNG = syscall.Errno(0x2c) -+ ECOMM = syscall.Errno(0x46) -+ ECONNABORTED = syscall.Errno(0x67) -+ ECONNREFUSED = syscall.Errno(0x6f) -+ ECONNRESET = syscall.Errno(0x68) -+ EDEADLK = syscall.Errno(0x23) -+ EDEADLOCK = syscall.Errno(0x23) -+ EDESTADDRREQ = syscall.Errno(0x59) -+ EDOM = syscall.Errno(0x21) -+ EDOTDOT = syscall.Errno(0x49) -+ EDQUOT = syscall.Errno(0x7a) -+ EEXIST = syscall.Errno(0x11) -+ EFAULT = syscall.Errno(0xe) -+ EFBIG = syscall.Errno(0x1b) -+ EHOSTDOWN = syscall.Errno(0x70) -+ EHOSTUNREACH = syscall.Errno(0x71) -+ EHWPOISON = syscall.Errno(0x85) -+ EIDRM = syscall.Errno(0x2b) -+ EILSEQ = syscall.Errno(0x54) -+ EINPROGRESS = syscall.Errno(0x73) -+ EINTR = syscall.Errno(0x4) -+ EINVAL = syscall.Errno(0x16) -+ EIO = syscall.Errno(0x5) -+ EISCONN = syscall.Errno(0x6a) -+ EISDIR = syscall.Errno(0x15) -+ EISNAM = syscall.Errno(0x78) -+ EKEYEXPIRED = syscall.Errno(0x7f) -+ EKEYREJECTED = syscall.Errno(0x81) -+ EKEYREVOKED = syscall.Errno(0x80) -+ EL2HLT = syscall.Errno(0x33) -+ EL2NSYNC = syscall.Errno(0x2d) -+ EL3HLT = syscall.Errno(0x2e) -+ EL3RST = syscall.Errno(0x2f) -+ ELIBACC = syscall.Errno(0x4f) -+ ELIBBAD = syscall.Errno(0x50) -+ ELIBEXEC = syscall.Errno(0x53) -+ ELIBMAX = syscall.Errno(0x52) -+ ELIBSCN = syscall.Errno(0x51) -+ ELNRNG = syscall.Errno(0x30) -+ ELOOP = syscall.Errno(0x28) -+ EMEDIUMTYPE = syscall.Errno(0x7c) -+ EMFILE = syscall.Errno(0x18) -+ EMLINK = syscall.Errno(0x1f) -+ EMSGSIZE = syscall.Errno(0x5a) -+ EMULTIHOP = syscall.Errno(0x48) -+ ENAMETOOLONG = syscall.Errno(0x24) -+ ENAVAIL = syscall.Errno(0x77) -+ ENETDOWN = syscall.Errno(0x64) -+ ENETRESET = syscall.Errno(0x66) -+ ENETUNREACH = syscall.Errno(0x65) -+ ENFILE = syscall.Errno(0x17) -+ ENOANO = syscall.Errno(0x37) -+ ENOBUFS = syscall.Errno(0x69) -+ ENOCSI = syscall.Errno(0x32) -+ ENODATA = syscall.Errno(0x3d) -+ ENODEV = syscall.Errno(0x13) -+ ENOENT = syscall.Errno(0x2) -+ ENOEXEC = syscall.Errno(0x8) -+ ENOKEY = syscall.Errno(0x7e) -+ ENOLCK = syscall.Errno(0x25) -+ ENOLINK = syscall.Errno(0x43) -+ ENOMEDIUM = syscall.Errno(0x7b) -+ ENOMEM = syscall.Errno(0xc) -+ ENOMSG = syscall.Errno(0x2a) -+ ENONET = syscall.Errno(0x40) -+ ENOPKG = syscall.Errno(0x41) -+ ENOPROTOOPT = syscall.Errno(0x5c) -+ ENOSPC = syscall.Errno(0x1c) -+ ENOSR = syscall.Errno(0x3f) -+ ENOSTR = syscall.Errno(0x3c) -+ ENOSYS = syscall.Errno(0x26) -+ ENOTBLK = syscall.Errno(0xf) -+ ENOTCONN = syscall.Errno(0x6b) -+ ENOTDIR = syscall.Errno(0x14) -+ ENOTEMPTY = syscall.Errno(0x27) -+ ENOTNAM = syscall.Errno(0x76) -+ ENOTRECOVERABLE = syscall.Errno(0x83) -+ ENOTSOCK = syscall.Errno(0x58) -+ ENOTSUP = syscall.Errno(0x5f) -+ ENOTTY = syscall.Errno(0x19) -+ ENOTUNIQ = syscall.Errno(0x4c) -+ ENXIO = syscall.Errno(0x6) -+ EOPNOTSUPP = syscall.Errno(0x5f) -+ EOVERFLOW = syscall.Errno(0x4b) -+ EOWNERDEAD = syscall.Errno(0x82) -+ EPERM = syscall.Errno(0x1) -+ EPFNOSUPPORT = syscall.Errno(0x60) -+ EPIPE = syscall.Errno(0x20) -+ EPROTO = syscall.Errno(0x47) -+ EPROTONOSUPPORT = syscall.Errno(0x5d) -+ EPROTOTYPE = syscall.Errno(0x5b) -+ ERANGE = syscall.Errno(0x22) -+ EREMCHG = syscall.Errno(0x4e) -+ EREMOTE = syscall.Errno(0x42) -+ EREMOTEIO = syscall.Errno(0x79) -+ ERESTART = syscall.Errno(0x55) -+ ERFKILL = syscall.Errno(0x84) -+ EROFS = syscall.Errno(0x1e) -+ ESHUTDOWN = syscall.Errno(0x6c) -+ ESOCKTNOSUPPORT = syscall.Errno(0x5e) -+ ESPIPE = syscall.Errno(0x1d) -+ ESRCH = syscall.Errno(0x3) -+ ESRMNT = syscall.Errno(0x45) -+ ESTALE = syscall.Errno(0x74) -+ ESTRPIPE = syscall.Errno(0x56) -+ ETIME = syscall.Errno(0x3e) -+ ETIMEDOUT = syscall.Errno(0x6e) -+ ETOOMANYREFS = syscall.Errno(0x6d) -+ ETXTBSY = syscall.Errno(0x1a) -+ EUCLEAN = syscall.Errno(0x75) -+ EUNATCH = syscall.Errno(0x31) -+ EUSERS = syscall.Errno(0x57) -+ EWOULDBLOCK = syscall.Errno(0xb) -+ EXDEV = syscall.Errno(0x12) -+ EXFULL = syscall.Errno(0x36) -+) -+ -+// Signals -+const ( -+ SIGABRT = syscall.Signal(0x6) -+ SIGALRM = syscall.Signal(0xe) -+ SIGBUS = syscall.Signal(0x7) -+ SIGCHLD = syscall.Signal(0x11) -+ SIGCLD = syscall.Signal(0x11) -+ SIGCONT = syscall.Signal(0x12) -+ SIGFPE = syscall.Signal(0x8) -+ SIGHUP = syscall.Signal(0x1) -+ SIGILL = syscall.Signal(0x4) -+ SIGINT = syscall.Signal(0x2) -+ SIGIO = syscall.Signal(0x1d) -+ SIGIOT = syscall.Signal(0x6) -+ SIGKILL = syscall.Signal(0x9) -+ SIGPIPE = syscall.Signal(0xd) -+ SIGPOLL = syscall.Signal(0x1d) -+ SIGPROF = syscall.Signal(0x1b) -+ SIGPWR = syscall.Signal(0x1e) -+ SIGQUIT = syscall.Signal(0x3) -+ SIGSEGV = syscall.Signal(0xb) -+ SIGSTKFLT = syscall.Signal(0x10) -+ SIGSTOP = syscall.Signal(0x13) -+ SIGSYS = syscall.Signal(0x1f) -+ SIGTERM = syscall.Signal(0xf) -+ SIGTRAP = syscall.Signal(0x5) -+ SIGTSTP = syscall.Signal(0x14) -+ SIGTTIN = syscall.Signal(0x15) -+ SIGTTOU = syscall.Signal(0x16) -+ SIGURG = syscall.Signal(0x17) -+ SIGUSR1 = syscall.Signal(0xa) -+ SIGUSR2 = syscall.Signal(0xc) -+ SIGVTALRM = syscall.Signal(0x1a) -+ SIGWINCH = syscall.Signal(0x1c) -+ SIGXCPU = syscall.Signal(0x18) -+ SIGXFSZ = syscall.Signal(0x19) -+) -+ -+// Error table -+var errorList = [...]struct { -+ num syscall.Errno -+ name string -+ desc string -+}{ -+ {1, "EPERM", "operation not permitted"}, -+ {2, "ENOENT", "no such file or directory"}, -+ {3, "ESRCH", "no such process"}, -+ {4, "EINTR", "interrupted system call"}, -+ {5, "EIO", "input/output error"}, -+ {6, "ENXIO", "no such device or address"}, -+ {7, "E2BIG", "argument list too long"}, -+ {8, "ENOEXEC", "exec format error"}, -+ {9, "EBADF", "bad file descriptor"}, -+ {10, "ECHILD", "no child processes"}, -+ {11, "EAGAIN", "resource temporarily unavailable"}, -+ {12, "ENOMEM", "cannot allocate memory"}, -+ {13, "EACCES", "permission denied"}, -+ {14, "EFAULT", "bad address"}, -+ {15, "ENOTBLK", "block device required"}, -+ {16, "EBUSY", "device or resource busy"}, -+ {17, "EEXIST", "file exists"}, -+ {18, "EXDEV", "invalid cross-device link"}, -+ {19, "ENODEV", "no such device"}, -+ {20, "ENOTDIR", "not a directory"}, -+ {21, "EISDIR", "is a directory"}, -+ {22, "EINVAL", "invalid argument"}, -+ {23, "ENFILE", "too many open files in system"}, -+ {24, "EMFILE", "too many open files"}, -+ {25, "ENOTTY", "inappropriate ioctl for device"}, -+ {26, "ETXTBSY", "text file busy"}, -+ {27, "EFBIG", "file too large"}, -+ {28, "ENOSPC", "no space left on device"}, -+ {29, "ESPIPE", "illegal seek"}, -+ {30, "EROFS", "read-only file system"}, -+ {31, "EMLINK", "too many links"}, -+ {32, "EPIPE", "broken pipe"}, -+ {33, "EDOM", "numerical argument out of domain"}, -+ {34, "ERANGE", "numerical result out of range"}, -+ {35, "EDEADLK", "resource deadlock avoided"}, -+ {36, "ENAMETOOLONG", "file name too long"}, -+ {37, "ENOLCK", "no locks available"}, -+ {38, "ENOSYS", "function not implemented"}, -+ {39, "ENOTEMPTY", "directory not empty"}, -+ {40, "ELOOP", "too many levels of symbolic links"}, -+ {42, "ENOMSG", "no message of desired type"}, -+ {43, "EIDRM", "identifier removed"}, -+ {44, "ECHRNG", "channel number out of range"}, -+ {45, "EL2NSYNC", "level 2 not synchronized"}, -+ {46, "EL3HLT", "level 3 halted"}, -+ {47, "EL3RST", "level 3 reset"}, -+ {48, "ELNRNG", "link number out of range"}, -+ {49, "EUNATCH", "protocol driver not attached"}, -+ {50, "ENOCSI", "no CSI structure available"}, -+ {51, "EL2HLT", "level 2 halted"}, -+ {52, "EBADE", "invalid exchange"}, -+ {53, "EBADR", "invalid request descriptor"}, -+ {54, "EXFULL", "exchange full"}, -+ {55, "ENOANO", "no anode"}, -+ {56, "EBADRQC", "invalid request code"}, -+ {57, "EBADSLT", "invalid slot"}, -+ {59, "EBFONT", "bad font file format"}, -+ {60, "ENOSTR", "device not a stream"}, -+ {61, "ENODATA", "no data available"}, -+ {62, "ETIME", "timer expired"}, -+ {63, "ENOSR", "out of streams resources"}, -+ {64, "ENONET", "machine is not on the network"}, -+ {65, "ENOPKG", "package not installed"}, -+ {66, "EREMOTE", "object is remote"}, -+ {67, "ENOLINK", "link has been severed"}, -+ {68, "EADV", "advertise error"}, -+ {69, "ESRMNT", "srmount error"}, -+ {70, "ECOMM", "communication error on send"}, -+ {71, "EPROTO", "protocol error"}, -+ {72, "EMULTIHOP", "multihop attempted"}, -+ {73, "EDOTDOT", "RFS specific error"}, -+ {74, "EBADMSG", "bad message"}, -+ {75, "EOVERFLOW", "value too large for defined data type"}, -+ {76, "ENOTUNIQ", "name not unique on network"}, -+ {77, "EBADFD", "file descriptor in bad state"}, -+ {78, "EREMCHG", "remote address changed"}, -+ {79, "ELIBACC", "can not access a needed shared library"}, -+ {80, "ELIBBAD", "accessing a corrupted shared library"}, -+ {81, "ELIBSCN", ".lib section in a.out corrupted"}, -+ {82, "ELIBMAX", "attempting to link in too many shared libraries"}, -+ {83, "ELIBEXEC", "cannot exec a shared library directly"}, -+ {84, "EILSEQ", "invalid or incomplete multibyte or wide character"}, -+ {85, "ERESTART", "interrupted system call should be restarted"}, -+ {86, "ESTRPIPE", "streams pipe error"}, -+ {87, "EUSERS", "too many users"}, -+ {88, "ENOTSOCK", "socket operation on non-socket"}, -+ {89, "EDESTADDRREQ", "destination address required"}, -+ {90, "EMSGSIZE", "message too long"}, -+ {91, "EPROTOTYPE", "protocol wrong type for socket"}, -+ {92, "ENOPROTOOPT", "protocol not available"}, -+ {93, "EPROTONOSUPPORT", "protocol not supported"}, -+ {94, "ESOCKTNOSUPPORT", "socket type not supported"}, -+ {95, "ENOTSUP", "operation not supported"}, -+ {96, "EPFNOSUPPORT", "protocol family not supported"}, -+ {97, "EAFNOSUPPORT", "address family not supported by protocol"}, -+ {98, "EADDRINUSE", "address already in use"}, -+ {99, "EADDRNOTAVAIL", "cannot assign requested address"}, -+ {100, "ENETDOWN", "network is down"}, -+ {101, "ENETUNREACH", "network is unreachable"}, -+ {102, "ENETRESET", "network dropped connection on reset"}, -+ {103, "ECONNABORTED", "software caused connection abort"}, -+ {104, "ECONNRESET", "connection reset by peer"}, -+ {105, "ENOBUFS", "no buffer space available"}, -+ {106, "EISCONN", "transport endpoint is already connected"}, -+ {107, "ENOTCONN", "transport endpoint is not connected"}, -+ {108, "ESHUTDOWN", "cannot send after transport endpoint shutdown"}, -+ {109, "ETOOMANYREFS", "too many references: cannot splice"}, -+ {110, "ETIMEDOUT", "connection timed out"}, -+ {111, "ECONNREFUSED", "connection refused"}, -+ {112, "EHOSTDOWN", "host is down"}, -+ {113, "EHOSTUNREACH", "no route to host"}, -+ {114, "EALREADY", "operation already in progress"}, -+ {115, "EINPROGRESS", "operation now in progress"}, -+ {116, "ESTALE", "stale file handle"}, -+ {117, "EUCLEAN", "structure needs cleaning"}, -+ {118, "ENOTNAM", "not a XENIX named type file"}, -+ {119, "ENAVAIL", "no XENIX semaphores available"}, -+ {120, "EISNAM", "is a named type file"}, -+ {121, "EREMOTEIO", "remote I/O error"}, -+ {122, "EDQUOT", "disk quota exceeded"}, -+ {123, "ENOMEDIUM", "no medium found"}, -+ {124, "EMEDIUMTYPE", "wrong medium type"}, -+ {125, "ECANCELED", "operation canceled"}, -+ {126, "ENOKEY", "required key not available"}, -+ {127, "EKEYEXPIRED", "key has expired"}, -+ {128, "EKEYREVOKED", "key has been revoked"}, -+ {129, "EKEYREJECTED", "key was rejected by service"}, -+ {130, "EOWNERDEAD", "owner died"}, -+ {131, "ENOTRECOVERABLE", "state not recoverable"}, -+ {132, "ERFKILL", "operation not possible due to RF-kill"}, -+ {133, "EHWPOISON", "memory page has hardware error"}, -+} -+ -+// Signal table -+var signalList = [...]struct { -+ num syscall.Signal -+ name string -+ desc string -+}{ -+ {1, "SIGHUP", "hangup"}, -+ {2, "SIGINT", "interrupt"}, -+ {3, "SIGQUIT", "quit"}, -+ {4, "SIGILL", "illegal instruction"}, -+ {5, "SIGTRAP", "trace/breakpoint trap"}, -+ {6, "SIGABRT", "aborted"}, -+ {7, "SIGBUS", "bus error"}, -+ {8, "SIGFPE", "floating point exception"}, -+ {9, "SIGKILL", "killed"}, -+ {10, "SIGUSR1", "user defined signal 1"}, -+ {11, "SIGSEGV", "segmentation fault"}, -+ {12, "SIGUSR2", "user defined signal 2"}, -+ {13, "SIGPIPE", "broken pipe"}, -+ {14, "SIGALRM", "alarm clock"}, -+ {15, "SIGTERM", "terminated"}, -+ {16, "SIGSTKFLT", "stack fault"}, -+ {17, "SIGCHLD", "child exited"}, -+ {18, "SIGCONT", "continued"}, -+ {19, "SIGSTOP", "stopped (signal)"}, -+ {20, "SIGTSTP", "stopped"}, -+ {21, "SIGTTIN", "stopped (tty input)"}, -+ {22, "SIGTTOU", "stopped (tty output)"}, -+ {23, "SIGURG", "urgent I/O condition"}, -+ {24, "SIGXCPU", "CPU time limit exceeded"}, -+ {25, "SIGXFSZ", "file size limit exceeded"}, -+ {26, "SIGVTALRM", "virtual timer expired"}, -+ {27, "SIGPROF", "profiling timer expired"}, -+ {28, "SIGWINCH", "window changed"}, -+ {29, "SIGIO", "I/O possible"}, -+ {30, "SIGPWR", "power failure"}, -+ {31, "SIGSYS", "bad system call"}, -+} -diff --git a/components/cli/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go b/components/cli/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go -new file mode 100644 -index 0000000..996eba5 ---- /dev/null -+++ b/components/cli/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go -@@ -0,0 +1,2188 @@ -+// go run mksyscall.go -tags linux,riscv64 syscall_linux.go syscall_linux_riscv64.go -+// Code generated by the command above; see README.md. DO NOT EDIT. -+ -+// +build linux,riscv64 -+ -+package unix -+ -+import ( -+ "syscall" -+ "unsafe" -+) -+ -+var _ syscall.Errno -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func fchmodat(dirfd int, path string, mode uint32) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func ioctl(fd int, req uint, arg uintptr) (err error) { -+ _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(oldpath) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(newpath) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_LINKAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { -+ r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 unsafe.Pointer -+ if len(buf) > 0 { -+ _p1 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p1 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(oldpath) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(newpath) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Unlinkat(dirfd int, path string, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getcwd(buf []byte) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { -+ r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) -+ wpid = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func KeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) { -+ r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) -+ ret = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func KeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(_p0), uintptr(len(buf)), uintptr(arg5), 0) -+ ret = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func keyctlJoin(cmd int, arg2 string) (ret int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(arg2) -+ if err != nil { -+ return -+ } -+ r0, _, e1 := Syscall(SYS_KEYCTL, uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0) -+ ret = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func keyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(arg3) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(arg4) -+ if err != nil { -+ return -+ } -+ r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(arg5), 0) -+ ret = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func keyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) { -+ var _p0 unsafe.Pointer -+ if len(payload) > 0 { -+ _p0 = unsafe.Pointer(&payload[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(_p0), uintptr(len(payload)), uintptr(arg5), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func keyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(unsafe.Pointer(arg2)), uintptr(_p0), uintptr(len(buf)), 0, 0) -+ ret = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { -+ _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(arg) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(source) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(target) -+ if err != nil { -+ return -+ } -+ var _p2 *byte -+ _p2, err = BytePtrFromString(fstype) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Acct(path string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(keyType) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(description) -+ if err != nil { -+ return -+ } -+ var _p2 unsafe.Pointer -+ if len(payload) > 0 { -+ _p2 = unsafe.Pointer(&payload[0]) -+ } else { -+ _p2 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_ADD_KEY, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(payload)), uintptr(ringid), 0) -+ id = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Adjtimex(buf *Timex) (state int, err error) { -+ r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0) -+ state = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Chdir(path string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Chroot(path string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func ClockGetres(clockid int32, res *Timespec) (err error) { -+ _, _, e1 := Syscall(SYS_CLOCK_GETRES, uintptr(clockid), uintptr(unsafe.Pointer(res)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func ClockGettime(clockid int32, time *Timespec) (err error) { -+ _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { -+ _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Close(fd int) (err error) { -+ _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) { -+ r0, _, e1 := Syscall6(SYS_COPY_FILE_RANGE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func DeleteModule(name string, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(name) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Dup(oldfd int) (fd int, err error) { -+ r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Dup3(oldfd int, newfd int, flags int) (err error) { -+ _, _, e1 := Syscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func EpollCreate1(flag int) (fd int, err error) { -+ r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { -+ _, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Eventfd(initval uint, flags int) (fd int, err error) { -+ r0, _, e1 := Syscall(SYS_EVENTFD2, uintptr(initval), uintptr(flags), 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Exit(code int) { -+ SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { -+ _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fchdir(fd int) (err error) { -+ _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fchmod(fd int, mode uint32) (err error) { -+ _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func fcntl(fd int, cmd int, arg int) (val int, err error) { -+ r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg)) -+ val = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fdatasync(fd int) (err error) { -+ _, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p1 unsafe.Pointer -+ if len(dest) > 0 { -+ _p1 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p1 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func FinitModule(fd int, params string, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(params) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Flistxattr(fd int, dest []byte) (sz int, err error) { -+ var _p0 unsafe.Pointer -+ if len(dest) > 0 { -+ _p0 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Flock(fd int, how int) (err error) { -+ _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fremovexattr(fd int, attr string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p1 unsafe.Pointer -+ if len(dest) > 0 { -+ _p1 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p1 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fsync(fd int) (err error) { -+ _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getdents(fd int, buf []byte) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf))) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getpgid(pid int) (pgid int, err error) { -+ r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0) -+ pgid = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getpid() (pid int) { -+ r0, _ := RawSyscallNoError(SYS_GETPID, 0, 0, 0) -+ pid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getppid() (ppid int) { -+ r0, _ := RawSyscallNoError(SYS_GETPPID, 0, 0, 0) -+ ppid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getpriority(which int, who int) (prio int, err error) { -+ r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0) -+ prio = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getrandom(buf []byte, flags int) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_GETRANDOM, uintptr(_p0), uintptr(len(buf)), uintptr(flags)) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getrusage(who int, rusage *Rusage) (err error) { -+ _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getsid(pid int) (sid int, err error) { -+ r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) -+ sid = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Gettid() (tid int) { -+ r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) -+ tid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getxattr(path string, attr string, dest []byte) (sz int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p2 unsafe.Pointer -+ if len(dest) > 0 { -+ _p2 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p2 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func InitModule(moduleImage []byte, params string) (err error) { -+ var _p0 unsafe.Pointer -+ if len(moduleImage) > 0 { -+ _p0 = unsafe.Pointer(&moduleImage[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(params) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1))) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(pathname) -+ if err != nil { -+ return -+ } -+ r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask)) -+ watchdesc = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func InotifyInit1(flags int) (fd int, err error) { -+ r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) { -+ r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0) -+ success = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Kill(pid int, sig syscall.Signal) (err error) { -+ _, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Klogctl(typ int, buf []byte) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf))) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Lgetxattr(path string, attr string, dest []byte) (sz int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p2 unsafe.Pointer -+ if len(dest) > 0 { -+ _p2 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p2 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_LGETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Listxattr(path string, dest []byte) (sz int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 unsafe.Pointer -+ if len(dest) > 0 { -+ _p1 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p1 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest))) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Llistxattr(path string, dest []byte) (sz int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 unsafe.Pointer -+ if len(dest) > 0 { -+ _p1 = unsafe.Pointer(&dest[0]) -+ } else { -+ _p1 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_LLISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest))) -+ sz = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Lremovexattr(path string, attr string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_LREMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Lsetxattr(path string, attr string, data []byte, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p2 unsafe.Pointer -+ if len(data) > 0 { -+ _p2 = unsafe.Pointer(&data[0]) -+ } else { -+ _p2 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall6(SYS_LSETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func MemfdCreate(name string, flags int) (fd int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(name) -+ if err != nil { -+ return -+ } -+ r0, _, e1 := Syscall(SYS_MEMFD_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Mkdirat(dirfd int, path string, mode uint32) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Nanosleep(time *Timespec, leftover *Timespec) (err error) { -+ _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { -+ r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func PivotRoot(newroot string, putold string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(newroot) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(putold) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { -+ _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) { -+ _, _, e1 := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { -+ r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func read(fd int, p []byte) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Removexattr(path string, attr string) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(oldpath) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(newpath) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(keyType) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(description) -+ if err != nil { -+ return -+ } -+ var _p2 *byte -+ _p2, err = BytePtrFromString(callback) -+ if err != nil { -+ return -+ } -+ r0, _, e1 := Syscall6(SYS_REQUEST_KEY, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(destRingid), 0, 0) -+ id = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setdomainname(p []byte) (err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Sethostname(p []byte) (err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setpgid(pid int, pgid int) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setsid() (pid int, err error) { -+ r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) -+ pid = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Settimeofday(tv *Timeval) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setns(fd int, nstype int) (err error) { -+ _, _, e1 := Syscall(SYS_SETNS, uintptr(fd), uintptr(nstype), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setpriority(which int, who int, prio int) (err error) { -+ _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setxattr(path string, attr string, data []byte, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ var _p1 *byte -+ _p1, err = BytePtrFromString(attr) -+ if err != nil { -+ return -+ } -+ var _p2 unsafe.Pointer -+ if len(data) > 0 { -+ _p2 = unsafe.Pointer(&data[0]) -+ } else { -+ _p2 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Signalfd(fd int, mask *Sigset_t, flags int) { -+ SyscallNoError(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(mask)), uintptr(flags)) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Sync() { -+ SyscallNoError(SYS_SYNC, 0, 0, 0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Syncfs(fd int) (err error) { -+ _, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Sysinfo(info *Sysinfo_t) (err error) { -+ _, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) { -+ r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0) -+ n = int64(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) { -+ _, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Times(tms *Tms) (ticks uintptr, err error) { -+ r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0) -+ ticks = uintptr(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Umask(mask int) (oldmask int) { -+ r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) -+ oldmask = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Uname(buf *Utsname) (err error) { -+ _, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Unmount(target string, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(target) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Unshare(flags int) (err error) { -+ _, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func write(fd int, p []byte) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p))) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func exitThread(code int) (err error) { -+ _, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func readlen(fd int, p *byte, np int) (n int, err error) { -+ r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np)) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func writelen(fd int, p *byte, np int) (n int, err error) { -+ r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np)) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func munmap(addr uintptr, length uintptr) (err error) { -+ _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Madvise(b []byte, advice int) (err error) { -+ var _p0 unsafe.Pointer -+ if len(b) > 0 { -+ _p0 = unsafe.Pointer(&b[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Mprotect(b []byte, prot int) (err error) { -+ var _p0 unsafe.Pointer -+ if len(b) > 0 { -+ _p0 = unsafe.Pointer(&b[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Mlock(b []byte) (err error) { -+ var _p0 unsafe.Pointer -+ if len(b) > 0 { -+ _p0 = unsafe.Pointer(&b[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Mlockall(flags int) (err error) { -+ _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Msync(b []byte, flags int) (err error) { -+ var _p0 unsafe.Pointer -+ if len(b) > 0 { -+ _p0 = unsafe.Pointer(&b[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Munlock(b []byte) (err error) { -+ var _p0 unsafe.Pointer -+ if len(b) > 0 { -+ _p0 = unsafe.Pointer(&b[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Munlockall() (err error) { -+ _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func faccessat(dirfd int, path string, mode uint32) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(events) > 0 { -+ _p0 = unsafe.Pointer(&events[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_EPOLL_PWAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fadvise(fd int, offset int64, length int64, advice int) (err error) { -+ _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fchown(fd int, uid int, gid int) (err error) { -+ _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fstat(fd int, stat *Stat_t) (err error) { -+ _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Fstatfs(fd int, buf *Statfs_t) (err error) { -+ _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Ftruncate(fd int, length int64) (err error) { -+ _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getegid() (egid int) { -+ r0, _ := RawSyscallNoError(SYS_GETEGID, 0, 0, 0) -+ egid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Geteuid() (euid int) { -+ r0, _ := RawSyscallNoError(SYS_GETEUID, 0, 0, 0) -+ euid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getgid() (gid int) { -+ r0, _ := RawSyscallNoError(SYS_GETGID, 0, 0, 0) -+ gid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getrlimit(resource int, rlim *Rlimit) (err error) { -+ _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Getuid() (uid int) { -+ r0, _ := RawSyscallNoError(SYS_GETUID, 0, 0, 0) -+ uid = int(r0) -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Listen(s int, n int) (err error) { -+ _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Pread(fd int, p []byte, offset int64) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Pwrite(fd int, p []byte, offset int64) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Seek(fd int, offset int64, whence int) (off int64, err error) { -+ r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) -+ off = int64(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { -+ r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) -+ written = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setfsgid(gid int) (err error) { -+ _, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setfsuid(uid int) (err error) { -+ _, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setregid(rgid int, egid int) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setresgid(rgid int, egid int, sgid int) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setresuid(ruid int, euid int, suid int) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setrlimit(resource int, rlim *Rlimit) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Setreuid(ruid int, euid int) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Shutdown(fd int, how int) (err error) { -+ _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) { -+ r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) -+ n = int64(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Statfs(path string, buf *Statfs_t) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func SyncFileRange(fd int, off int64, n int64, flags int) (err error) { -+ _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Truncate(path string, length int64) (err error) { -+ var _p0 *byte -+ _p0, err = BytePtrFromString(path) -+ if err != nil { -+ return -+ } -+ _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { -+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) { -+ r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { -+ _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { -+ _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func getgroups(n int, list *_Gid_t) (nn int, err error) { -+ r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0) -+ nn = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func setgroups(n int, list *_Gid_t) (err error) { -+ _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { -+ _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { -+ _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func socket(domain int, typ int, proto int) (fd int, err error) { -+ r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto)) -+ fd = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { -+ _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { -+ _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { -+ _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { -+ var _p0 unsafe.Pointer -+ if len(p) > 0 { -+ _p0 = unsafe.Pointer(&p[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { -+ var _p0 unsafe.Pointer -+ if len(buf) > 0 { -+ _p0 = unsafe.Pointer(&buf[0]) -+ } else { -+ _p0 = unsafe.Pointer(&_zero) -+ } -+ _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { -+ r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { -+ r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) -+ n = int(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { -+ r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)) -+ xaddr = uintptr(r0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func Gettimeofday(tv *Timeval) (err error) { -+ _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -+ -+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -+ -+func pipe2(p *[2]_C_int, flags int) (err error) { -+ _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) -+ if e1 != 0 { -+ err = errnoErr(e1) -+ } -+ return -+} -diff --git a/components/cli/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/components/cli/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go -new file mode 100644 -index 0000000..473c746 ---- /dev/null -+++ b/components/cli/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go -@@ -0,0 +1,287 @@ -+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h -+// Code generated by the command above; see README.md. DO NOT EDIT. -+ -+// +build riscv64,linux -+ -+package unix -+ -+const ( -+ SYS_IO_SETUP = 0 -+ SYS_IO_DESTROY = 1 -+ SYS_IO_SUBMIT = 2 -+ SYS_IO_CANCEL = 3 -+ SYS_IO_GETEVENTS = 4 -+ SYS_SETXATTR = 5 -+ SYS_LSETXATTR = 6 -+ SYS_FSETXATTR = 7 -+ SYS_GETXATTR = 8 -+ SYS_LGETXATTR = 9 -+ SYS_FGETXATTR = 10 -+ SYS_LISTXATTR = 11 -+ SYS_LLISTXATTR = 12 -+ SYS_FLISTXATTR = 13 -+ SYS_REMOVEXATTR = 14 -+ SYS_LREMOVEXATTR = 15 -+ SYS_FREMOVEXATTR = 16 -+ SYS_GETCWD = 17 -+ SYS_LOOKUP_DCOOKIE = 18 -+ SYS_EVENTFD2 = 19 -+ SYS_EPOLL_CREATE1 = 20 -+ SYS_EPOLL_CTL = 21 -+ SYS_EPOLL_PWAIT = 22 -+ SYS_DUP = 23 -+ SYS_DUP3 = 24 -+ SYS_FCNTL = 25 -+ SYS_INOTIFY_INIT1 = 26 -+ SYS_INOTIFY_ADD_WATCH = 27 -+ SYS_INOTIFY_RM_WATCH = 28 -+ SYS_IOCTL = 29 -+ SYS_IOPRIO_SET = 30 -+ SYS_IOPRIO_GET = 31 -+ SYS_FLOCK = 32 -+ SYS_MKNODAT = 33 -+ SYS_MKDIRAT = 34 -+ SYS_UNLINKAT = 35 -+ SYS_SYMLINKAT = 36 -+ SYS_LINKAT = 37 -+ SYS_UMOUNT2 = 39 -+ SYS_MOUNT = 40 -+ SYS_PIVOT_ROOT = 41 -+ SYS_NFSSERVCTL = 42 -+ SYS_STATFS = 43 -+ SYS_FSTATFS = 44 -+ SYS_TRUNCATE = 45 -+ SYS_FTRUNCATE = 46 -+ SYS_FALLOCATE = 47 -+ SYS_FACCESSAT = 48 -+ SYS_CHDIR = 49 -+ SYS_FCHDIR = 50 -+ SYS_CHROOT = 51 -+ SYS_FCHMOD = 52 -+ SYS_FCHMODAT = 53 -+ SYS_FCHOWNAT = 54 -+ SYS_FCHOWN = 55 -+ SYS_OPENAT = 56 -+ SYS_CLOSE = 57 -+ SYS_VHANGUP = 58 -+ SYS_PIPE2 = 59 -+ SYS_QUOTACTL = 60 -+ SYS_GETDENTS64 = 61 -+ SYS_LSEEK = 62 -+ SYS_READ = 63 -+ SYS_WRITE = 64 -+ SYS_READV = 65 -+ SYS_WRITEV = 66 -+ SYS_PREAD64 = 67 -+ SYS_PWRITE64 = 68 -+ SYS_PREADV = 69 -+ SYS_PWRITEV = 70 -+ SYS_SENDFILE = 71 -+ SYS_PSELECT6 = 72 -+ SYS_PPOLL = 73 -+ SYS_SIGNALFD4 = 74 -+ SYS_VMSPLICE = 75 -+ SYS_SPLICE = 76 -+ SYS_TEE = 77 -+ SYS_READLINKAT = 78 -+ SYS_FSTATAT = 79 -+ SYS_FSTAT = 80 -+ SYS_SYNC = 81 -+ SYS_FSYNC = 82 -+ SYS_FDATASYNC = 83 -+ SYS_SYNC_FILE_RANGE = 84 -+ SYS_TIMERFD_CREATE = 85 -+ SYS_TIMERFD_SETTIME = 86 -+ SYS_TIMERFD_GETTIME = 87 -+ SYS_UTIMENSAT = 88 -+ SYS_ACCT = 89 -+ SYS_CAPGET = 90 -+ SYS_CAPSET = 91 -+ SYS_PERSONALITY = 92 -+ SYS_EXIT = 93 -+ SYS_EXIT_GROUP = 94 -+ SYS_WAITID = 95 -+ SYS_SET_TID_ADDRESS = 96 -+ SYS_UNSHARE = 97 -+ SYS_FUTEX = 98 -+ SYS_SET_ROBUST_LIST = 99 -+ SYS_GET_ROBUST_LIST = 100 -+ SYS_NANOSLEEP = 101 -+ SYS_GETITIMER = 102 -+ SYS_SETITIMER = 103 -+ SYS_KEXEC_LOAD = 104 -+ SYS_INIT_MODULE = 105 -+ SYS_DELETE_MODULE = 106 -+ SYS_TIMER_CREATE = 107 -+ SYS_TIMER_GETTIME = 108 -+ SYS_TIMER_GETOVERRUN = 109 -+ SYS_TIMER_SETTIME = 110 -+ SYS_TIMER_DELETE = 111 -+ SYS_CLOCK_SETTIME = 112 -+ SYS_CLOCK_GETTIME = 113 -+ SYS_CLOCK_GETRES = 114 -+ SYS_CLOCK_NANOSLEEP = 115 -+ SYS_SYSLOG = 116 -+ SYS_PTRACE = 117 -+ SYS_SCHED_SETPARAM = 118 -+ SYS_SCHED_SETSCHEDULER = 119 -+ SYS_SCHED_GETSCHEDULER = 120 -+ SYS_SCHED_GETPARAM = 121 -+ SYS_SCHED_SETAFFINITY = 122 -+ SYS_SCHED_GETAFFINITY = 123 -+ SYS_SCHED_YIELD = 124 -+ SYS_SCHED_GET_PRIORITY_MAX = 125 -+ SYS_SCHED_GET_PRIORITY_MIN = 126 -+ SYS_SCHED_RR_GET_INTERVAL = 127 -+ SYS_RESTART_SYSCALL = 128 -+ SYS_KILL = 129 -+ SYS_TKILL = 130 -+ SYS_TGKILL = 131 -+ SYS_SIGALTSTACK = 132 -+ SYS_RT_SIGSUSPEND = 133 -+ SYS_RT_SIGACTION = 134 -+ SYS_RT_SIGPROCMASK = 135 -+ SYS_RT_SIGPENDING = 136 -+ SYS_RT_SIGTIMEDWAIT = 137 -+ SYS_RT_SIGQUEUEINFO = 138 -+ SYS_RT_SIGRETURN = 139 -+ SYS_SETPRIORITY = 140 -+ SYS_GETPRIORITY = 141 -+ SYS_REBOOT = 142 -+ SYS_SETREGID = 143 -+ SYS_SETGID = 144 -+ SYS_SETREUID = 145 -+ SYS_SETUID = 146 -+ SYS_SETRESUID = 147 -+ SYS_GETRESUID = 148 -+ SYS_SETRESGID = 149 -+ SYS_GETRESGID = 150 -+ SYS_SETFSUID = 151 -+ SYS_SETFSGID = 152 -+ SYS_TIMES = 153 -+ SYS_SETPGID = 154 -+ SYS_GETPGID = 155 -+ SYS_GETSID = 156 -+ SYS_SETSID = 157 -+ SYS_GETGROUPS = 158 -+ SYS_SETGROUPS = 159 -+ SYS_UNAME = 160 -+ SYS_SETHOSTNAME = 161 -+ SYS_SETDOMAINNAME = 162 -+ SYS_GETRLIMIT = 163 -+ SYS_SETRLIMIT = 164 -+ SYS_GETRUSAGE = 165 -+ SYS_UMASK = 166 -+ SYS_PRCTL = 167 -+ SYS_GETCPU = 168 -+ SYS_GETTIMEOFDAY = 169 -+ SYS_SETTIMEOFDAY = 170 -+ SYS_ADJTIMEX = 171 -+ SYS_GETPID = 172 -+ SYS_GETPPID = 173 -+ SYS_GETUID = 174 -+ SYS_GETEUID = 175 -+ SYS_GETGID = 176 -+ SYS_GETEGID = 177 -+ SYS_GETTID = 178 -+ SYS_SYSINFO = 179 -+ SYS_MQ_OPEN = 180 -+ SYS_MQ_UNLINK = 181 -+ SYS_MQ_TIMEDSEND = 182 -+ SYS_MQ_TIMEDRECEIVE = 183 -+ SYS_MQ_NOTIFY = 184 -+ SYS_MQ_GETSETATTR = 185 -+ SYS_MSGGET = 186 -+ SYS_MSGCTL = 187 -+ SYS_MSGRCV = 188 -+ SYS_MSGSND = 189 -+ SYS_SEMGET = 190 -+ SYS_SEMCTL = 191 -+ SYS_SEMTIMEDOP = 192 -+ SYS_SEMOP = 193 -+ SYS_SHMGET = 194 -+ SYS_SHMCTL = 195 -+ SYS_SHMAT = 196 -+ SYS_SHMDT = 197 -+ SYS_SOCKET = 198 -+ SYS_SOCKETPAIR = 199 -+ SYS_BIND = 200 -+ SYS_LISTEN = 201 -+ SYS_ACCEPT = 202 -+ SYS_CONNECT = 203 -+ SYS_GETSOCKNAME = 204 -+ SYS_GETPEERNAME = 205 -+ SYS_SENDTO = 206 -+ SYS_RECVFROM = 207 -+ SYS_SETSOCKOPT = 208 -+ SYS_GETSOCKOPT = 209 -+ SYS_SHUTDOWN = 210 -+ SYS_SENDMSG = 211 -+ SYS_RECVMSG = 212 -+ SYS_READAHEAD = 213 -+ SYS_BRK = 214 -+ SYS_MUNMAP = 215 -+ SYS_MREMAP = 216 -+ SYS_ADD_KEY = 217 -+ SYS_REQUEST_KEY = 218 -+ SYS_KEYCTL = 219 -+ SYS_CLONE = 220 -+ SYS_EXECVE = 221 -+ SYS_MMAP = 222 -+ SYS_FADVISE64 = 223 -+ SYS_SWAPON = 224 -+ SYS_SWAPOFF = 225 -+ SYS_MPROTECT = 226 -+ SYS_MSYNC = 227 -+ SYS_MLOCK = 228 -+ SYS_MUNLOCK = 229 -+ SYS_MLOCKALL = 230 -+ SYS_MUNLOCKALL = 231 -+ SYS_MINCORE = 232 -+ SYS_MADVISE = 233 -+ SYS_REMAP_FILE_PAGES = 234 -+ SYS_MBIND = 235 -+ SYS_GET_MEMPOLICY = 236 -+ SYS_SET_MEMPOLICY = 237 -+ SYS_MIGRATE_PAGES = 238 -+ SYS_MOVE_PAGES = 239 -+ SYS_RT_TGSIGQUEUEINFO = 240 -+ SYS_PERF_EVENT_OPEN = 241 -+ SYS_ACCEPT4 = 242 -+ SYS_RECVMMSG = 243 -+ SYS_ARCH_SPECIFIC_SYSCALL = 244 -+ SYS_WAIT4 = 260 -+ SYS_PRLIMIT64 = 261 -+ SYS_FANOTIFY_INIT = 262 -+ SYS_FANOTIFY_MARK = 263 -+ SYS_NAME_TO_HANDLE_AT = 264 -+ SYS_OPEN_BY_HANDLE_AT = 265 -+ SYS_CLOCK_ADJTIME = 266 -+ SYS_SYNCFS = 267 -+ SYS_SETNS = 268 -+ SYS_SENDMMSG = 269 -+ SYS_PROCESS_VM_READV = 270 -+ SYS_PROCESS_VM_WRITEV = 271 -+ SYS_KCMP = 272 -+ SYS_FINIT_MODULE = 273 -+ SYS_SCHED_SETATTR = 274 -+ SYS_SCHED_GETATTR = 275 -+ SYS_RENAMEAT2 = 276 -+ SYS_SECCOMP = 277 -+ SYS_GETRANDOM = 278 -+ SYS_MEMFD_CREATE = 279 -+ SYS_BPF = 280 -+ SYS_EXECVEAT = 281 -+ SYS_USERFAULTFD = 282 -+ SYS_MEMBARRIER = 283 -+ SYS_MLOCK2 = 284 -+ SYS_COPY_FILE_RANGE = 285 -+ SYS_PREADV2 = 286 -+ SYS_PWRITEV2 = 287 -+ SYS_PKEY_MPROTECT = 288 -+ SYS_PKEY_ALLOC = 289 -+ SYS_PKEY_FREE = 290 -+ SYS_STATX = 291 -+ SYS_IO_PGETEVENTS = 292 -+ SYS_RSEQ = 293 -+) -diff --git a/components/cli/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/components/cli/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go -new file mode 100644 -index 0000000..f6d02d7 ---- /dev/null -+++ b/components/cli/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go -@@ -0,0 +1,2046 @@ -+// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go -+// Code generated by the command above; see README.md. DO NOT EDIT. -+ -+// +build riscv64,linux -+ -+package unix -+ -+const ( -+ sizeofPtr = 0x8 -+ sizeofShort = 0x2 -+ sizeofInt = 0x4 -+ sizeofLong = 0x8 -+ sizeofLongLong = 0x8 -+ PathMax = 0x1000 -+) -+ -+type ( -+ _C_short int16 -+ _C_int int32 -+ _C_long int64 -+ _C_long_long int64 -+) -+ -+type Timespec struct { -+ Sec int64 -+ Nsec int64 -+} -+ -+type Timeval struct { -+ Sec int64 -+ Usec int64 -+} -+ -+type Timex struct { -+ Modes uint32 -+ Offset int64 -+ Freq int64 -+ Maxerror int64 -+ Esterror int64 -+ Status int32 -+ Constant int64 -+ Precision int64 -+ Tolerance int64 -+ Time Timeval -+ Tick int64 -+ Ppsfreq int64 -+ Jitter int64 -+ Shift int32 -+ Stabil int64 -+ Jitcnt int64 -+ Calcnt int64 -+ Errcnt int64 -+ Stbcnt int64 -+ Tai int32 -+ _ [44]byte -+} -+ -+type Time_t int64 -+ -+type Tms struct { -+ Utime int64 -+ Stime int64 -+ Cutime int64 -+ Cstime int64 -+} -+ -+type Utimbuf struct { -+ Actime int64 -+ Modtime int64 -+} -+ -+type Rusage struct { -+ Utime Timeval -+ Stime Timeval -+ Maxrss int64 -+ Ixrss int64 -+ Idrss int64 -+ Isrss int64 -+ Minflt int64 -+ Majflt int64 -+ Nswap int64 -+ Inblock int64 -+ Oublock int64 -+ Msgsnd int64 -+ Msgrcv int64 -+ Nsignals int64 -+ Nvcsw int64 -+ Nivcsw int64 -+} -+ -+type Rlimit struct { -+ Cur uint64 -+ Max uint64 -+} -+ -+type _Gid_t uint32 -+ -+type Stat_t struct { -+ Dev uint64 -+ Ino uint64 -+ Mode uint32 -+ Nlink uint32 -+ Uid uint32 -+ Gid uint32 -+ Rdev uint64 -+ _ uint64 -+ Size int64 -+ Blksize int32 -+ _ int32 -+ Blocks int64 -+ Atim Timespec -+ Mtim Timespec -+ Ctim Timespec -+ _ [2]int32 -+} -+ -+type StatxTimestamp struct { -+ Sec int64 -+ Nsec uint32 -+ _ int32 -+} -+ -+type Statx_t struct { -+ Mask uint32 -+ Blksize uint32 -+ Attributes uint64 -+ Nlink uint32 -+ Uid uint32 -+ Gid uint32 -+ Mode uint16 -+ _ [1]uint16 -+ Ino uint64 -+ Size uint64 -+ Blocks uint64 -+ Attributes_mask uint64 -+ Atime StatxTimestamp -+ Btime StatxTimestamp -+ Ctime StatxTimestamp -+ Mtime StatxTimestamp -+ Rdev_major uint32 -+ Rdev_minor uint32 -+ Dev_major uint32 -+ Dev_minor uint32 -+ _ [14]uint64 -+} -+ -+type Dirent struct { -+ Ino uint64 -+ Off int64 -+ Reclen uint16 -+ Type uint8 -+ Name [256]uint8 -+ _ [5]byte -+} -+ -+type Fsid struct { -+ Val [2]int32 -+} -+ -+type Flock_t struct { -+ Type int16 -+ Whence int16 -+ Start int64 -+ Len int64 -+ Pid int32 -+ _ [4]byte -+} -+ -+type FscryptPolicy struct { -+ Version uint8 -+ Contents_encryption_mode uint8 -+ Filenames_encryption_mode uint8 -+ Flags uint8 -+ Master_key_descriptor [8]uint8 -+} -+ -+type FscryptKey struct { -+ Mode uint32 -+ Raw [64]uint8 -+ Size uint32 -+} -+ -+type KeyctlDHParams struct { -+ Private int32 -+ Prime int32 -+ Base int32 -+} -+ -+const ( -+ FADV_NORMAL = 0x0 -+ FADV_RANDOM = 0x1 -+ FADV_SEQUENTIAL = 0x2 -+ FADV_WILLNEED = 0x3 -+ FADV_DONTNEED = 0x4 -+ FADV_NOREUSE = 0x5 -+) -+ -+type RawSockaddrInet4 struct { -+ Family uint16 -+ Port uint16 -+ Addr [4]byte /* in_addr */ -+ Zero [8]uint8 -+} -+ -+type RawSockaddrInet6 struct { -+ Family uint16 -+ Port uint16 -+ Flowinfo uint32 -+ Addr [16]byte /* in6_addr */ -+ Scope_id uint32 -+} -+ -+type RawSockaddrUnix struct { -+ Family uint16 -+ Path [108]int8 -+} -+ -+type RawSockaddrLinklayer struct { -+ Family uint16 -+ Protocol uint16 -+ Ifindex int32 -+ Hatype uint16 -+ Pkttype uint8 -+ Halen uint8 -+ Addr [8]uint8 -+} -+ -+type RawSockaddrNetlink struct { -+ Family uint16 -+ Pad uint16 -+ Pid uint32 -+ Groups uint32 -+} -+ -+type RawSockaddrHCI struct { -+ Family uint16 -+ Dev uint16 -+ Channel uint16 -+} -+ -+type RawSockaddrL2 struct { -+ Family uint16 -+ Psm uint16 -+ Bdaddr [6]uint8 -+ Cid uint16 -+ Bdaddr_type uint8 -+ _ [1]byte -+} -+ -+type RawSockaddrRFCOMM struct { -+ Family uint16 -+ Bdaddr [6]uint8 -+ Channel uint8 -+ _ [1]byte -+} -+ -+type RawSockaddrCAN struct { -+ Family uint16 -+ Ifindex int32 -+ Addr [8]byte -+} -+ -+type RawSockaddrALG struct { -+ Family uint16 -+ Type [14]uint8 -+ Feat uint32 -+ Mask uint32 -+ Name [64]uint8 -+} -+ -+type RawSockaddrVM struct { -+ Family uint16 -+ Reserved1 uint16 -+ Port uint32 -+ Cid uint32 -+ Zero [4]uint8 -+} -+ -+type RawSockaddrXDP struct { -+ Family uint16 -+ Flags uint16 -+ Ifindex uint32 -+ Queue_id uint32 -+ Shared_umem_fd uint32 -+} -+ -+type RawSockaddrPPPoX [0x1e]byte -+ -+type RawSockaddr struct { -+ Family uint16 -+ Data [14]uint8 -+} -+ -+type RawSockaddrAny struct { -+ Addr RawSockaddr -+ Pad [96]uint8 -+} -+ -+type _Socklen uint32 -+ -+type Linger struct { -+ Onoff int32 -+ Linger int32 -+} -+ -+type Iovec struct { -+ Base *byte -+ Len uint64 -+} -+ -+type IPMreq struct { -+ Multiaddr [4]byte /* in_addr */ -+ Interface [4]byte /* in_addr */ -+} -+ -+type IPMreqn struct { -+ Multiaddr [4]byte /* in_addr */ -+ Address [4]byte /* in_addr */ -+ Ifindex int32 -+} -+ -+type IPv6Mreq struct { -+ Multiaddr [16]byte /* in6_addr */ -+ Interface uint32 -+} -+ -+type PacketMreq struct { -+ Ifindex int32 -+ Type uint16 -+ Alen uint16 -+ Address [8]uint8 -+} -+ -+type Msghdr struct { -+ Name *byte -+ Namelen uint32 -+ Iov *Iovec -+ Iovlen uint64 -+ Control *byte -+ Controllen uint64 -+ Flags int32 -+ _ [4]byte -+} -+ -+type Cmsghdr struct { -+ Len uint64 -+ Level int32 -+ Type int32 -+} -+ -+type Inet4Pktinfo struct { -+ Ifindex int32 -+ Spec_dst [4]byte /* in_addr */ -+ Addr [4]byte /* in_addr */ -+} -+ -+type Inet6Pktinfo struct { -+ Addr [16]byte /* in6_addr */ -+ Ifindex uint32 -+} -+ -+type IPv6MTUInfo struct { -+ Addr RawSockaddrInet6 -+ Mtu uint32 -+} -+ -+type ICMPv6Filter struct { -+ Data [8]uint32 -+} -+ -+type Ucred struct { -+ Pid int32 -+ Uid uint32 -+ Gid uint32 -+} -+ -+type TCPInfo struct { -+ State uint8 -+ Ca_state uint8 -+ Retransmits uint8 -+ Probes uint8 -+ Backoff uint8 -+ Options uint8 -+ Rto uint32 -+ Ato uint32 -+ Snd_mss uint32 -+ Rcv_mss uint32 -+ Unacked uint32 -+ Sacked uint32 -+ Lost uint32 -+ Retrans uint32 -+ Fackets uint32 -+ Last_data_sent uint32 -+ Last_ack_sent uint32 -+ Last_data_recv uint32 -+ Last_ack_recv uint32 -+ Pmtu uint32 -+ Rcv_ssthresh uint32 -+ Rtt uint32 -+ Rttvar uint32 -+ Snd_ssthresh uint32 -+ Snd_cwnd uint32 -+ Advmss uint32 -+ Reordering uint32 -+ Rcv_rtt uint32 -+ Rcv_space uint32 -+ Total_retrans uint32 -+} -+ -+const ( -+ SizeofSockaddrInet4 = 0x10 -+ SizeofSockaddrInet6 = 0x1c -+ SizeofSockaddrAny = 0x70 -+ SizeofSockaddrUnix = 0x6e -+ SizeofSockaddrLinklayer = 0x14 -+ SizeofSockaddrNetlink = 0xc -+ SizeofSockaddrHCI = 0x6 -+ SizeofSockaddrL2 = 0xe -+ SizeofSockaddrRFCOMM = 0xa -+ SizeofSockaddrCAN = 0x10 -+ SizeofSockaddrALG = 0x58 -+ SizeofSockaddrVM = 0x10 -+ SizeofSockaddrXDP = 0x10 -+ SizeofSockaddrPPPoX = 0x1e -+ SizeofLinger = 0x8 -+ SizeofIovec = 0x10 -+ SizeofIPMreq = 0x8 -+ SizeofIPMreqn = 0xc -+ SizeofIPv6Mreq = 0x14 -+ SizeofPacketMreq = 0x10 -+ SizeofMsghdr = 0x38 -+ SizeofCmsghdr = 0x10 -+ SizeofInet4Pktinfo = 0xc -+ SizeofInet6Pktinfo = 0x14 -+ SizeofIPv6MTUInfo = 0x20 -+ SizeofICMPv6Filter = 0x20 -+ SizeofUcred = 0xc -+ SizeofTCPInfo = 0x68 -+) -+ -+const ( -+ IFA_UNSPEC = 0x0 -+ IFA_ADDRESS = 0x1 -+ IFA_LOCAL = 0x2 -+ IFA_LABEL = 0x3 -+ IFA_BROADCAST = 0x4 -+ IFA_ANYCAST = 0x5 -+ IFA_CACHEINFO = 0x6 -+ IFA_MULTICAST = 0x7 -+ IFLA_UNSPEC = 0x0 -+ IFLA_ADDRESS = 0x1 -+ IFLA_BROADCAST = 0x2 -+ IFLA_IFNAME = 0x3 -+ IFLA_INFO_KIND = 0x1 -+ IFLA_MTU = 0x4 -+ IFLA_LINK = 0x5 -+ IFLA_QDISC = 0x6 -+ IFLA_STATS = 0x7 -+ IFLA_COST = 0x8 -+ IFLA_PRIORITY = 0x9 -+ IFLA_MASTER = 0xa -+ IFLA_WIRELESS = 0xb -+ IFLA_PROTINFO = 0xc -+ IFLA_TXQLEN = 0xd -+ IFLA_MAP = 0xe -+ IFLA_WEIGHT = 0xf -+ IFLA_OPERSTATE = 0x10 -+ IFLA_LINKMODE = 0x11 -+ IFLA_LINKINFO = 0x12 -+ IFLA_NET_NS_PID = 0x13 -+ IFLA_IFALIAS = 0x14 -+ IFLA_NUM_VF = 0x15 -+ IFLA_VFINFO_LIST = 0x16 -+ IFLA_STATS64 = 0x17 -+ IFLA_VF_PORTS = 0x18 -+ IFLA_PORT_SELF = 0x19 -+ IFLA_AF_SPEC = 0x1a -+ IFLA_GROUP = 0x1b -+ IFLA_NET_NS_FD = 0x1c -+ IFLA_EXT_MASK = 0x1d -+ IFLA_PROMISCUITY = 0x1e -+ IFLA_NUM_TX_QUEUES = 0x1f -+ IFLA_NUM_RX_QUEUES = 0x20 -+ IFLA_CARRIER = 0x21 -+ IFLA_PHYS_PORT_ID = 0x22 -+ IFLA_CARRIER_CHANGES = 0x23 -+ IFLA_PHYS_SWITCH_ID = 0x24 -+ IFLA_LINK_NETNSID = 0x25 -+ IFLA_PHYS_PORT_NAME = 0x26 -+ IFLA_PROTO_DOWN = 0x27 -+ IFLA_GSO_MAX_SEGS = 0x28 -+ IFLA_GSO_MAX_SIZE = 0x29 -+ IFLA_PAD = 0x2a -+ IFLA_XDP = 0x2b -+ IFLA_EVENT = 0x2c -+ IFLA_NEW_NETNSID = 0x2d -+ IFLA_IF_NETNSID = 0x2e -+ IFLA_MAX = 0x33 -+ RT_SCOPE_UNIVERSE = 0x0 -+ RT_SCOPE_SITE = 0xc8 -+ RT_SCOPE_LINK = 0xfd -+ RT_SCOPE_HOST = 0xfe -+ RT_SCOPE_NOWHERE = 0xff -+ RT_TABLE_UNSPEC = 0x0 -+ RT_TABLE_COMPAT = 0xfc -+ RT_TABLE_DEFAULT = 0xfd -+ RT_TABLE_MAIN = 0xfe -+ RT_TABLE_LOCAL = 0xff -+ RT_TABLE_MAX = 0xffffffff -+ RTA_UNSPEC = 0x0 -+ RTA_DST = 0x1 -+ RTA_SRC = 0x2 -+ RTA_IIF = 0x3 -+ RTA_OIF = 0x4 -+ RTA_GATEWAY = 0x5 -+ RTA_PRIORITY = 0x6 -+ RTA_PREFSRC = 0x7 -+ RTA_METRICS = 0x8 -+ RTA_MULTIPATH = 0x9 -+ RTA_FLOW = 0xb -+ RTA_CACHEINFO = 0xc -+ RTA_TABLE = 0xf -+ RTA_MARK = 0x10 -+ RTA_MFC_STATS = 0x11 -+ RTA_VIA = 0x12 -+ RTA_NEWDST = 0x13 -+ RTA_PREF = 0x14 -+ RTA_ENCAP_TYPE = 0x15 -+ RTA_ENCAP = 0x16 -+ RTA_EXPIRES = 0x17 -+ RTA_PAD = 0x18 -+ RTA_UID = 0x19 -+ RTA_TTL_PROPAGATE = 0x1a -+ RTA_IP_PROTO = 0x1b -+ RTA_SPORT = 0x1c -+ RTA_DPORT = 0x1d -+ RTN_UNSPEC = 0x0 -+ RTN_UNICAST = 0x1 -+ RTN_LOCAL = 0x2 -+ RTN_BROADCAST = 0x3 -+ RTN_ANYCAST = 0x4 -+ RTN_MULTICAST = 0x5 -+ RTN_BLACKHOLE = 0x6 -+ RTN_UNREACHABLE = 0x7 -+ RTN_PROHIBIT = 0x8 -+ RTN_THROW = 0x9 -+ RTN_NAT = 0xa -+ RTN_XRESOLVE = 0xb -+ RTNLGRP_NONE = 0x0 -+ RTNLGRP_LINK = 0x1 -+ RTNLGRP_NOTIFY = 0x2 -+ RTNLGRP_NEIGH = 0x3 -+ RTNLGRP_TC = 0x4 -+ RTNLGRP_IPV4_IFADDR = 0x5 -+ RTNLGRP_IPV4_MROUTE = 0x6 -+ RTNLGRP_IPV4_ROUTE = 0x7 -+ RTNLGRP_IPV4_RULE = 0x8 -+ RTNLGRP_IPV6_IFADDR = 0x9 -+ RTNLGRP_IPV6_MROUTE = 0xa -+ RTNLGRP_IPV6_ROUTE = 0xb -+ RTNLGRP_IPV6_IFINFO = 0xc -+ RTNLGRP_IPV6_PREFIX = 0x12 -+ RTNLGRP_IPV6_RULE = 0x13 -+ RTNLGRP_ND_USEROPT = 0x14 -+ SizeofNlMsghdr = 0x10 -+ SizeofNlMsgerr = 0x14 -+ SizeofRtGenmsg = 0x1 -+ SizeofNlAttr = 0x4 -+ SizeofRtAttr = 0x4 -+ SizeofIfInfomsg = 0x10 -+ SizeofIfAddrmsg = 0x8 -+ SizeofRtMsg = 0xc -+ SizeofRtNexthop = 0x8 -+) -+ -+type NlMsghdr struct { -+ Len uint32 -+ Type uint16 -+ Flags uint16 -+ Seq uint32 -+ Pid uint32 -+} -+ -+type NlMsgerr struct { -+ Error int32 -+ Msg NlMsghdr -+} -+ -+type RtGenmsg struct { -+ Family uint8 -+} -+ -+type NlAttr struct { -+ Len uint16 -+ Type uint16 -+} -+ -+type RtAttr struct { -+ Len uint16 -+ Type uint16 -+} -+ -+type IfInfomsg struct { -+ Family uint8 -+ _ uint8 -+ Type uint16 -+ Index int32 -+ Flags uint32 -+ Change uint32 -+} -+ -+type IfAddrmsg struct { -+ Family uint8 -+ Prefixlen uint8 -+ Flags uint8 -+ Scope uint8 -+ Index uint32 -+} -+ -+type RtMsg struct { -+ Family uint8 -+ Dst_len uint8 -+ Src_len uint8 -+ Tos uint8 -+ Table uint8 -+ Protocol uint8 -+ Scope uint8 -+ Type uint8 -+ Flags uint32 -+} -+ -+type RtNexthop struct { -+ Len uint16 -+ Flags uint8 -+ Hops uint8 -+ Ifindex int32 -+} -+ -+const ( -+ SizeofSockFilter = 0x8 -+ SizeofSockFprog = 0x10 -+) -+ -+type SockFilter struct { -+ Code uint16 -+ Jt uint8 -+ Jf uint8 -+ K uint32 -+} -+ -+type SockFprog struct { -+ Len uint16 -+ Filter *SockFilter -+} -+ -+type InotifyEvent struct { -+ Wd int32 -+ Mask uint32 -+ Cookie uint32 -+ Len uint32 -+} -+ -+const SizeofInotifyEvent = 0x10 -+ -+type PtraceRegs struct { -+ Pc uint64 -+ Ra uint64 -+ Sp uint64 -+ Gp uint64 -+ Tp uint64 -+ T0 uint64 -+ T1 uint64 -+ T2 uint64 -+ S0 uint64 -+ S1 uint64 -+ A0 uint64 -+ A1 uint64 -+ A2 uint64 -+ A3 uint64 -+ A4 uint64 -+ A5 uint64 -+ A6 uint64 -+ A7 uint64 -+ S2 uint64 -+ S3 uint64 -+ S4 uint64 -+ S5 uint64 -+ S6 uint64 -+ S7 uint64 -+ S8 uint64 -+ S9 uint64 -+ S10 uint64 -+ S11 uint64 -+ T3 uint64 -+ T4 uint64 -+ T5 uint64 -+ T6 uint64 -+} -+ -+type FdSet struct { -+ Bits [16]int64 -+} -+ -+type Sysinfo_t struct { -+ Uptime int64 -+ Loads [3]uint64 -+ Totalram uint64 -+ Freeram uint64 -+ Sharedram uint64 -+ Bufferram uint64 -+ Totalswap uint64 -+ Freeswap uint64 -+ Procs uint16 -+ Pad uint16 -+ Totalhigh uint64 -+ Freehigh uint64 -+ Unit uint32 -+ _ [0]uint8 -+ _ [4]byte -+} -+ -+type Utsname struct { -+ Sysname [65]byte -+ Nodename [65]byte -+ Release [65]byte -+ Version [65]byte -+ Machine [65]byte -+ Domainname [65]byte -+} -+ -+type Ustat_t struct { -+ Tfree int32 -+ Tinode uint64 -+ Fname [6]uint8 -+ Fpack [6]uint8 -+ _ [4]byte -+} -+ -+type EpollEvent struct { -+ Events uint32 -+ Fd int32 -+ Pad int32 -+} -+ -+const ( -+ AT_EMPTY_PATH = 0x1000 -+ AT_FDCWD = -0x64 -+ AT_NO_AUTOMOUNT = 0x800 -+ AT_REMOVEDIR = 0x200 -+ -+ AT_STATX_SYNC_AS_STAT = 0x0 -+ AT_STATX_FORCE_SYNC = 0x2000 -+ AT_STATX_DONT_SYNC = 0x4000 -+ -+ AT_SYMLINK_FOLLOW = 0x400 -+ AT_SYMLINK_NOFOLLOW = 0x100 -+ -+ AT_EACCESS = 0x200 -+) -+ -+type PollFd struct { -+ Fd int32 -+ Events int16 -+ Revents int16 -+} -+ -+const ( -+ POLLIN = 0x1 -+ POLLPRI = 0x2 -+ POLLOUT = 0x4 -+ POLLRDHUP = 0x2000 -+ POLLERR = 0x8 -+ POLLHUP = 0x10 -+ POLLNVAL = 0x20 -+) -+ -+type Sigset_t struct { -+ Val [16]uint64 -+} -+ -+type SignalfdSiginfo struct { -+ Signo uint32 -+ Errno int32 -+ Code int32 -+ Pid uint32 -+ Uid uint32 -+ Fd int32 -+ Tid uint32 -+ Band uint32 -+ Overrun uint32 -+ Trapno uint32 -+ Status int32 -+ Int int32 -+ Ptr uint64 -+ Utime uint64 -+ Stime uint64 -+ Addr uint64 -+ Addr_lsb uint16 -+ _ uint16 -+ Syscall int32 -+ Call_addr uint64 -+ Arch uint32 -+ _ [28]uint8 -+} -+ -+const PERF_IOC_FLAG_GROUP = 0x1 -+ -+type Termios struct { -+ Iflag uint32 -+ Oflag uint32 -+ Cflag uint32 -+ Lflag uint32 -+ Line uint8 -+ Cc [19]uint8 -+ Ispeed uint32 -+ Ospeed uint32 -+} -+ -+type Winsize struct { -+ Row uint16 -+ Col uint16 -+ Xpixel uint16 -+ Ypixel uint16 -+} -+ -+type Taskstats struct { -+ Version uint16 -+ Ac_exitcode uint32 -+ Ac_flag uint8 -+ Ac_nice uint8 -+ Cpu_count uint64 -+ Cpu_delay_total uint64 -+ Blkio_count uint64 -+ Blkio_delay_total uint64 -+ Swapin_count uint64 -+ Swapin_delay_total uint64 -+ Cpu_run_real_total uint64 -+ Cpu_run_virtual_total uint64 -+ Ac_comm [32]uint8 -+ Ac_sched uint8 -+ Ac_pad [3]uint8 -+ _ [4]byte -+ Ac_uid uint32 -+ Ac_gid uint32 -+ Ac_pid uint32 -+ Ac_ppid uint32 -+ Ac_btime uint32 -+ Ac_etime uint64 -+ Ac_utime uint64 -+ Ac_stime uint64 -+ Ac_minflt uint64 -+ Ac_majflt uint64 -+ Coremem uint64 -+ Virtmem uint64 -+ Hiwater_rss uint64 -+ Hiwater_vm uint64 -+ Read_char uint64 -+ Write_char uint64 -+ Read_syscalls uint64 -+ Write_syscalls uint64 -+ Read_bytes uint64 -+ Write_bytes uint64 -+ Cancelled_write_bytes uint64 -+ Nvcsw uint64 -+ Nivcsw uint64 -+ Ac_utimescaled uint64 -+ Ac_stimescaled uint64 -+ Cpu_scaled_run_real_total uint64 -+ Freepages_count uint64 -+ Freepages_delay_total uint64 -+ Thrashing_count uint64 -+ Thrashing_delay_total uint64 -+} -+ -+const ( -+ TASKSTATS_CMD_UNSPEC = 0x0 -+ TASKSTATS_CMD_GET = 0x1 -+ TASKSTATS_CMD_NEW = 0x2 -+ TASKSTATS_TYPE_UNSPEC = 0x0 -+ TASKSTATS_TYPE_PID = 0x1 -+ TASKSTATS_TYPE_TGID = 0x2 -+ TASKSTATS_TYPE_STATS = 0x3 -+ TASKSTATS_TYPE_AGGR_PID = 0x4 -+ TASKSTATS_TYPE_AGGR_TGID = 0x5 -+ TASKSTATS_TYPE_NULL = 0x6 -+ TASKSTATS_CMD_ATTR_UNSPEC = 0x0 -+ TASKSTATS_CMD_ATTR_PID = 0x1 -+ TASKSTATS_CMD_ATTR_TGID = 0x2 -+ TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 -+ TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 -+) -+ -+type CGroupStats struct { -+ Sleeping uint64 -+ Running uint64 -+ Stopped uint64 -+ Uninterruptible uint64 -+ Io_wait uint64 -+} -+ -+const ( -+ CGROUPSTATS_CMD_UNSPEC = 0x3 -+ CGROUPSTATS_CMD_GET = 0x4 -+ CGROUPSTATS_CMD_NEW = 0x5 -+ CGROUPSTATS_TYPE_UNSPEC = 0x0 -+ CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 -+ CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 -+ CGROUPSTATS_CMD_ATTR_FD = 0x1 -+) -+ -+type Genlmsghdr struct { -+ Cmd uint8 -+ Version uint8 -+ Reserved uint16 -+} -+ -+const ( -+ CTRL_CMD_UNSPEC = 0x0 -+ CTRL_CMD_NEWFAMILY = 0x1 -+ CTRL_CMD_DELFAMILY = 0x2 -+ CTRL_CMD_GETFAMILY = 0x3 -+ CTRL_CMD_NEWOPS = 0x4 -+ CTRL_CMD_DELOPS = 0x5 -+ CTRL_CMD_GETOPS = 0x6 -+ CTRL_CMD_NEWMCAST_GRP = 0x7 -+ CTRL_CMD_DELMCAST_GRP = 0x8 -+ CTRL_CMD_GETMCAST_GRP = 0x9 -+ CTRL_ATTR_UNSPEC = 0x0 -+ CTRL_ATTR_FAMILY_ID = 0x1 -+ CTRL_ATTR_FAMILY_NAME = 0x2 -+ CTRL_ATTR_VERSION = 0x3 -+ CTRL_ATTR_HDRSIZE = 0x4 -+ CTRL_ATTR_MAXATTR = 0x5 -+ CTRL_ATTR_OPS = 0x6 -+ CTRL_ATTR_MCAST_GROUPS = 0x7 -+ CTRL_ATTR_OP_UNSPEC = 0x0 -+ CTRL_ATTR_OP_ID = 0x1 -+ CTRL_ATTR_OP_FLAGS = 0x2 -+ CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 -+ CTRL_ATTR_MCAST_GRP_NAME = 0x1 -+ CTRL_ATTR_MCAST_GRP_ID = 0x2 -+) -+ -+type cpuMask uint64 -+ -+const ( -+ _CPU_SETSIZE = 0x400 -+ _NCPUBITS = 0x40 -+) -+ -+const ( -+ BDADDR_BREDR = 0x0 -+ BDADDR_LE_PUBLIC = 0x1 -+ BDADDR_LE_RANDOM = 0x2 -+) -+ -+type PerfEventAttr struct { -+ Type uint32 -+ Size uint32 -+ Config uint64 -+ Sample uint64 -+ Sample_type uint64 -+ Read_format uint64 -+ Bits uint64 -+ Wakeup uint32 -+ Bp_type uint32 -+ Ext1 uint64 -+ Ext2 uint64 -+ Branch_sample_type uint64 -+ Sample_regs_user uint64 -+ Sample_stack_user uint32 -+ Clockid int32 -+ Sample_regs_intr uint64 -+ Aux_watermark uint32 -+ _ uint32 -+} -+ -+type PerfEventMmapPage struct { -+ Version uint32 -+ Compat_version uint32 -+ Lock uint32 -+ Index uint32 -+ Offset int64 -+ Time_enabled uint64 -+ Time_running uint64 -+ Capabilities uint64 -+ Pmc_width uint16 -+ Time_shift uint16 -+ Time_mult uint32 -+ Time_offset uint64 -+ Time_zero uint64 -+ Size uint32 -+ _ [948]uint8 -+ Data_head uint64 -+ Data_tail uint64 -+ Data_offset uint64 -+ Data_size uint64 -+ Aux_head uint64 -+ Aux_tail uint64 -+ Aux_offset uint64 -+ Aux_size uint64 -+} -+ -+const ( -+ PerfBitDisabled uint64 = CBitFieldMaskBit0 -+ PerfBitInherit = CBitFieldMaskBit1 -+ PerfBitPinned = CBitFieldMaskBit2 -+ PerfBitExclusive = CBitFieldMaskBit3 -+ PerfBitExcludeUser = CBitFieldMaskBit4 -+ PerfBitExcludeKernel = CBitFieldMaskBit5 -+ PerfBitExcludeHv = CBitFieldMaskBit6 -+ PerfBitExcludeIdle = CBitFieldMaskBit7 -+ PerfBitMmap = CBitFieldMaskBit8 -+ PerfBitComm = CBitFieldMaskBit9 -+ PerfBitFreq = CBitFieldMaskBit10 -+ PerfBitInheritStat = CBitFieldMaskBit11 -+ PerfBitEnableOnExec = CBitFieldMaskBit12 -+ PerfBitTask = CBitFieldMaskBit13 -+ PerfBitWatermark = CBitFieldMaskBit14 -+ PerfBitPreciseIPBit1 = CBitFieldMaskBit15 -+ PerfBitPreciseIPBit2 = CBitFieldMaskBit16 -+ PerfBitMmapData = CBitFieldMaskBit17 -+ PerfBitSampleIDAll = CBitFieldMaskBit18 -+ PerfBitExcludeHost = CBitFieldMaskBit19 -+ PerfBitExcludeGuest = CBitFieldMaskBit20 -+ PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 -+ PerfBitExcludeCallchainUser = CBitFieldMaskBit22 -+ PerfBitMmap2 = CBitFieldMaskBit23 -+ PerfBitCommExec = CBitFieldMaskBit24 -+ PerfBitUseClockID = CBitFieldMaskBit25 -+ PerfBitContextSwitch = CBitFieldMaskBit26 -+) -+ -+const ( -+ PERF_TYPE_HARDWARE = 0x0 -+ PERF_TYPE_SOFTWARE = 0x1 -+ PERF_TYPE_TRACEPOINT = 0x2 -+ PERF_TYPE_HW_CACHE = 0x3 -+ PERF_TYPE_RAW = 0x4 -+ PERF_TYPE_BREAKPOINT = 0x5 -+ -+ PERF_COUNT_HW_CPU_CYCLES = 0x0 -+ PERF_COUNT_HW_INSTRUCTIONS = 0x1 -+ PERF_COUNT_HW_CACHE_REFERENCES = 0x2 -+ PERF_COUNT_HW_CACHE_MISSES = 0x3 -+ PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 -+ PERF_COUNT_HW_BRANCH_MISSES = 0x5 -+ PERF_COUNT_HW_BUS_CYCLES = 0x6 -+ PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 -+ PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 -+ PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 -+ -+ PERF_COUNT_HW_CACHE_L1D = 0x0 -+ PERF_COUNT_HW_CACHE_L1I = 0x1 -+ PERF_COUNT_HW_CACHE_LL = 0x2 -+ PERF_COUNT_HW_CACHE_DTLB = 0x3 -+ PERF_COUNT_HW_CACHE_ITLB = 0x4 -+ PERF_COUNT_HW_CACHE_BPU = 0x5 -+ PERF_COUNT_HW_CACHE_NODE = 0x6 -+ -+ PERF_COUNT_HW_CACHE_OP_READ = 0x0 -+ PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 -+ PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 -+ -+ PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 -+ PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 -+ -+ PERF_COUNT_SW_CPU_CLOCK = 0x0 -+ PERF_COUNT_SW_TASK_CLOCK = 0x1 -+ PERF_COUNT_SW_PAGE_FAULTS = 0x2 -+ PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 -+ PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 -+ PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 -+ PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 -+ PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 -+ PERF_COUNT_SW_EMULATION_FAULTS = 0x8 -+ PERF_COUNT_SW_DUMMY = 0x9 -+ -+ PERF_SAMPLE_IP = 0x1 -+ PERF_SAMPLE_TID = 0x2 -+ PERF_SAMPLE_TIME = 0x4 -+ PERF_SAMPLE_ADDR = 0x8 -+ PERF_SAMPLE_READ = 0x10 -+ PERF_SAMPLE_CALLCHAIN = 0x20 -+ PERF_SAMPLE_ID = 0x40 -+ PERF_SAMPLE_CPU = 0x80 -+ PERF_SAMPLE_PERIOD = 0x100 -+ PERF_SAMPLE_STREAM_ID = 0x200 -+ PERF_SAMPLE_RAW = 0x400 -+ PERF_SAMPLE_BRANCH_STACK = 0x800 -+ -+ PERF_SAMPLE_BRANCH_USER = 0x1 -+ PERF_SAMPLE_BRANCH_KERNEL = 0x2 -+ PERF_SAMPLE_BRANCH_HV = 0x4 -+ PERF_SAMPLE_BRANCH_ANY = 0x8 -+ PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 -+ PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 -+ PERF_SAMPLE_BRANCH_IND_CALL = 0x40 -+ -+ PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 -+ PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 -+ PERF_FORMAT_ID = 0x4 -+ PERF_FORMAT_GROUP = 0x8 -+ -+ PERF_RECORD_MMAP = 0x1 -+ PERF_RECORD_LOST = 0x2 -+ PERF_RECORD_COMM = 0x3 -+ PERF_RECORD_EXIT = 0x4 -+ PERF_RECORD_THROTTLE = 0x5 -+ PERF_RECORD_UNTHROTTLE = 0x6 -+ PERF_RECORD_FORK = 0x7 -+ PERF_RECORD_READ = 0x8 -+ PERF_RECORD_SAMPLE = 0x9 -+ -+ PERF_CONTEXT_HV = -0x20 -+ PERF_CONTEXT_KERNEL = -0x80 -+ PERF_CONTEXT_USER = -0x200 -+ -+ PERF_CONTEXT_GUEST = -0x800 -+ PERF_CONTEXT_GUEST_KERNEL = -0x880 -+ PERF_CONTEXT_GUEST_USER = -0xa00 -+ -+ PERF_FLAG_FD_NO_GROUP = 0x1 -+ PERF_FLAG_FD_OUTPUT = 0x2 -+ PERF_FLAG_PID_CGROUP = 0x4 -+) -+ -+const ( -+ CBitFieldMaskBit0 = 0x1 -+ CBitFieldMaskBit1 = 0x2 -+ CBitFieldMaskBit2 = 0x4 -+ CBitFieldMaskBit3 = 0x8 -+ CBitFieldMaskBit4 = 0x10 -+ CBitFieldMaskBit5 = 0x20 -+ CBitFieldMaskBit6 = 0x40 -+ CBitFieldMaskBit7 = 0x80 -+ CBitFieldMaskBit8 = 0x100 -+ CBitFieldMaskBit9 = 0x200 -+ CBitFieldMaskBit10 = 0x400 -+ CBitFieldMaskBit11 = 0x800 -+ CBitFieldMaskBit12 = 0x1000 -+ CBitFieldMaskBit13 = 0x2000 -+ CBitFieldMaskBit14 = 0x4000 -+ CBitFieldMaskBit15 = 0x8000 -+ CBitFieldMaskBit16 = 0x10000 -+ CBitFieldMaskBit17 = 0x20000 -+ CBitFieldMaskBit18 = 0x40000 -+ CBitFieldMaskBit19 = 0x80000 -+ CBitFieldMaskBit20 = 0x100000 -+ CBitFieldMaskBit21 = 0x200000 -+ CBitFieldMaskBit22 = 0x400000 -+ CBitFieldMaskBit23 = 0x800000 -+ CBitFieldMaskBit24 = 0x1000000 -+ CBitFieldMaskBit25 = 0x2000000 -+ CBitFieldMaskBit26 = 0x4000000 -+ CBitFieldMaskBit27 = 0x8000000 -+ CBitFieldMaskBit28 = 0x10000000 -+ CBitFieldMaskBit29 = 0x20000000 -+ CBitFieldMaskBit30 = 0x40000000 -+ CBitFieldMaskBit31 = 0x80000000 -+ CBitFieldMaskBit32 = 0x100000000 -+ CBitFieldMaskBit33 = 0x200000000 -+ CBitFieldMaskBit34 = 0x400000000 -+ CBitFieldMaskBit35 = 0x800000000 -+ CBitFieldMaskBit36 = 0x1000000000 -+ CBitFieldMaskBit37 = 0x2000000000 -+ CBitFieldMaskBit38 = 0x4000000000 -+ CBitFieldMaskBit39 = 0x8000000000 -+ CBitFieldMaskBit40 = 0x10000000000 -+ CBitFieldMaskBit41 = 0x20000000000 -+ CBitFieldMaskBit42 = 0x40000000000 -+ CBitFieldMaskBit43 = 0x80000000000 -+ CBitFieldMaskBit44 = 0x100000000000 -+ CBitFieldMaskBit45 = 0x200000000000 -+ CBitFieldMaskBit46 = 0x400000000000 -+ CBitFieldMaskBit47 = 0x800000000000 -+ CBitFieldMaskBit48 = 0x1000000000000 -+ CBitFieldMaskBit49 = 0x2000000000000 -+ CBitFieldMaskBit50 = 0x4000000000000 -+ CBitFieldMaskBit51 = 0x8000000000000 -+ CBitFieldMaskBit52 = 0x10000000000000 -+ CBitFieldMaskBit53 = 0x20000000000000 -+ CBitFieldMaskBit54 = 0x40000000000000 -+ CBitFieldMaskBit55 = 0x80000000000000 -+ CBitFieldMaskBit56 = 0x100000000000000 -+ CBitFieldMaskBit57 = 0x200000000000000 -+ CBitFieldMaskBit58 = 0x400000000000000 -+ CBitFieldMaskBit59 = 0x800000000000000 -+ CBitFieldMaskBit60 = 0x1000000000000000 -+ CBitFieldMaskBit61 = 0x2000000000000000 -+ CBitFieldMaskBit62 = 0x4000000000000000 -+ CBitFieldMaskBit63 = 0x8000000000000000 -+) -+ -+type SockaddrStorage struct { -+ Family uint16 -+ _ [118]uint8 -+ _ uint64 -+} -+ -+type TCPMD5Sig struct { -+ Addr SockaddrStorage -+ Flags uint8 -+ Prefixlen uint8 -+ Keylen uint16 -+ _ uint32 -+ Key [80]uint8 -+} -+ -+type HDDriveCmdHdr struct { -+ Command uint8 -+ Number uint8 -+ Feature uint8 -+ Count uint8 -+} -+ -+type HDGeometry struct { -+ Heads uint8 -+ Sectors uint8 -+ Cylinders uint16 -+ Start uint64 -+} -+ -+type HDDriveID struct { -+ Config uint16 -+ Cyls uint16 -+ Reserved2 uint16 -+ Heads uint16 -+ Track_bytes uint16 -+ Sector_bytes uint16 -+ Sectors uint16 -+ Vendor0 uint16 -+ Vendor1 uint16 -+ Vendor2 uint16 -+ Serial_no [20]uint8 -+ Buf_type uint16 -+ Buf_size uint16 -+ Ecc_bytes uint16 -+ Fw_rev [8]uint8 -+ Model [40]uint8 -+ Max_multsect uint8 -+ Vendor3 uint8 -+ Dword_io uint16 -+ Vendor4 uint8 -+ Capability uint8 -+ Reserved50 uint16 -+ Vendor5 uint8 -+ TPIO uint8 -+ Vendor6 uint8 -+ TDMA uint8 -+ Field_valid uint16 -+ Cur_cyls uint16 -+ Cur_heads uint16 -+ Cur_sectors uint16 -+ Cur_capacity0 uint16 -+ Cur_capacity1 uint16 -+ Multsect uint8 -+ Multsect_valid uint8 -+ Lba_capacity uint32 -+ Dma_1word uint16 -+ Dma_mword uint16 -+ Eide_pio_modes uint16 -+ Eide_dma_min uint16 -+ Eide_dma_time uint16 -+ Eide_pio uint16 -+ Eide_pio_iordy uint16 -+ Words69_70 [2]uint16 -+ Words71_74 [4]uint16 -+ Queue_depth uint16 -+ Words76_79 [4]uint16 -+ Major_rev_num uint16 -+ Minor_rev_num uint16 -+ Command_set_1 uint16 -+ Command_set_2 uint16 -+ Cfsse uint16 -+ Cfs_enable_1 uint16 -+ Cfs_enable_2 uint16 -+ Csf_default uint16 -+ Dma_ultra uint16 -+ Trseuc uint16 -+ TrsEuc uint16 -+ CurAPMvalues uint16 -+ Mprc uint16 -+ Hw_config uint16 -+ Acoustic uint16 -+ Msrqs uint16 -+ Sxfert uint16 -+ Sal uint16 -+ Spg uint32 -+ Lba_capacity_2 uint64 -+ Words104_125 [22]uint16 -+ Last_lun uint16 -+ Word127 uint16 -+ Dlf uint16 -+ Csfo uint16 -+ Words130_155 [26]uint16 -+ Word156 uint16 -+ Words157_159 [3]uint16 -+ Cfa_power uint16 -+ Words161_175 [15]uint16 -+ Words176_205 [30]uint16 -+ Words206_254 [49]uint16 -+ Integrity_word uint16 -+} -+ -+type Statfs_t struct { -+ Type int64 -+ Bsize int64 -+ Blocks uint64 -+ Bfree uint64 -+ Bavail uint64 -+ Files uint64 -+ Ffree uint64 -+ Fsid Fsid -+ Namelen int64 -+ Frsize int64 -+ Flags int64 -+ Spare [4]int64 -+} -+ -+const ( -+ ST_MANDLOCK = 0x40 -+ ST_NOATIME = 0x400 -+ ST_NODEV = 0x4 -+ ST_NODIRATIME = 0x800 -+ ST_NOEXEC = 0x8 -+ ST_NOSUID = 0x2 -+ ST_RDONLY = 0x1 -+ ST_RELATIME = 0x1000 -+ ST_SYNCHRONOUS = 0x10 -+) -+ -+type TpacketHdr struct { -+ Status uint64 -+ Len uint32 -+ Snaplen uint32 -+ Mac uint16 -+ Net uint16 -+ Sec uint32 -+ Usec uint32 -+ _ [4]byte -+} -+ -+type Tpacket2Hdr struct { -+ Status uint32 -+ Len uint32 -+ Snaplen uint32 -+ Mac uint16 -+ Net uint16 -+ Sec uint32 -+ Nsec uint32 -+ Vlan_tci uint16 -+ Vlan_tpid uint16 -+ _ [4]uint8 -+} -+ -+type Tpacket3Hdr struct { -+ Next_offset uint32 -+ Sec uint32 -+ Nsec uint32 -+ Snaplen uint32 -+ Len uint32 -+ Status uint32 -+ Mac uint16 -+ Net uint16 -+ Hv1 TpacketHdrVariant1 -+ _ [8]uint8 -+} -+ -+type TpacketHdrVariant1 struct { -+ Rxhash uint32 -+ Vlan_tci uint32 -+ Vlan_tpid uint16 -+ _ uint16 -+} -+ -+type TpacketBlockDesc struct { -+ Version uint32 -+ To_priv uint32 -+ Hdr [40]byte -+} -+ -+type TpacketReq struct { -+ Block_size uint32 -+ Block_nr uint32 -+ Frame_size uint32 -+ Frame_nr uint32 -+} -+ -+type TpacketReq3 struct { -+ Block_size uint32 -+ Block_nr uint32 -+ Frame_size uint32 -+ Frame_nr uint32 -+ Retire_blk_tov uint32 -+ Sizeof_priv uint32 -+ Feature_req_word uint32 -+} -+ -+type TpacketStats struct { -+ Packets uint32 -+ Drops uint32 -+} -+ -+type TpacketStatsV3 struct { -+ Packets uint32 -+ Drops uint32 -+ Freeze_q_cnt uint32 -+} -+ -+type TpacketAuxdata struct { -+ Status uint32 -+ Len uint32 -+ Snaplen uint32 -+ Mac uint16 -+ Net uint16 -+ Vlan_tci uint16 -+ Vlan_tpid uint16 -+} -+ -+const ( -+ TPACKET_V1 = 0x0 -+ TPACKET_V2 = 0x1 -+ TPACKET_V3 = 0x2 -+) -+ -+const ( -+ SizeofTpacketHdr = 0x20 -+ SizeofTpacket2Hdr = 0x20 -+ SizeofTpacket3Hdr = 0x30 -+) -+ -+const ( -+ NF_INET_PRE_ROUTING = 0x0 -+ NF_INET_LOCAL_IN = 0x1 -+ NF_INET_FORWARD = 0x2 -+ NF_INET_LOCAL_OUT = 0x3 -+ NF_INET_POST_ROUTING = 0x4 -+ NF_INET_NUMHOOKS = 0x5 -+) -+ -+const ( -+ NF_NETDEV_INGRESS = 0x0 -+ NF_NETDEV_NUMHOOKS = 0x1 -+) -+ -+const ( -+ NFPROTO_UNSPEC = 0x0 -+ NFPROTO_INET = 0x1 -+ NFPROTO_IPV4 = 0x2 -+ NFPROTO_ARP = 0x3 -+ NFPROTO_NETDEV = 0x5 -+ NFPROTO_BRIDGE = 0x7 -+ NFPROTO_IPV6 = 0xa -+ NFPROTO_DECNET = 0xc -+ NFPROTO_NUMPROTO = 0xd -+) -+ -+type Nfgenmsg struct { -+ Nfgen_family uint8 -+ Version uint8 -+ Res_id uint16 -+} -+ -+const ( -+ NFNL_BATCH_UNSPEC = 0x0 -+ NFNL_BATCH_GENID = 0x1 -+) -+ -+const ( -+ NFT_REG_VERDICT = 0x0 -+ NFT_REG_1 = 0x1 -+ NFT_REG_2 = 0x2 -+ NFT_REG_3 = 0x3 -+ NFT_REG_4 = 0x4 -+ NFT_REG32_00 = 0x8 -+ NFT_REG32_01 = 0x9 -+ NFT_REG32_02 = 0xa -+ NFT_REG32_03 = 0xb -+ NFT_REG32_04 = 0xc -+ NFT_REG32_05 = 0xd -+ NFT_REG32_06 = 0xe -+ NFT_REG32_07 = 0xf -+ NFT_REG32_08 = 0x10 -+ NFT_REG32_09 = 0x11 -+ NFT_REG32_10 = 0x12 -+ NFT_REG32_11 = 0x13 -+ NFT_REG32_12 = 0x14 -+ NFT_REG32_13 = 0x15 -+ NFT_REG32_14 = 0x16 -+ NFT_REG32_15 = 0x17 -+ NFT_CONTINUE = -0x1 -+ NFT_BREAK = -0x2 -+ NFT_JUMP = -0x3 -+ NFT_GOTO = -0x4 -+ NFT_RETURN = -0x5 -+ NFT_MSG_NEWTABLE = 0x0 -+ NFT_MSG_GETTABLE = 0x1 -+ NFT_MSG_DELTABLE = 0x2 -+ NFT_MSG_NEWCHAIN = 0x3 -+ NFT_MSG_GETCHAIN = 0x4 -+ NFT_MSG_DELCHAIN = 0x5 -+ NFT_MSG_NEWRULE = 0x6 -+ NFT_MSG_GETRULE = 0x7 -+ NFT_MSG_DELRULE = 0x8 -+ NFT_MSG_NEWSET = 0x9 -+ NFT_MSG_GETSET = 0xa -+ NFT_MSG_DELSET = 0xb -+ NFT_MSG_NEWSETELEM = 0xc -+ NFT_MSG_GETSETELEM = 0xd -+ NFT_MSG_DELSETELEM = 0xe -+ NFT_MSG_NEWGEN = 0xf -+ NFT_MSG_GETGEN = 0x10 -+ NFT_MSG_TRACE = 0x11 -+ NFT_MSG_NEWOBJ = 0x12 -+ NFT_MSG_GETOBJ = 0x13 -+ NFT_MSG_DELOBJ = 0x14 -+ NFT_MSG_GETOBJ_RESET = 0x15 -+ NFT_MSG_MAX = 0x19 -+ NFTA_LIST_UNPEC = 0x0 -+ NFTA_LIST_ELEM = 0x1 -+ NFTA_HOOK_UNSPEC = 0x0 -+ NFTA_HOOK_HOOKNUM = 0x1 -+ NFTA_HOOK_PRIORITY = 0x2 -+ NFTA_HOOK_DEV = 0x3 -+ NFT_TABLE_F_DORMANT = 0x1 -+ NFTA_TABLE_UNSPEC = 0x0 -+ NFTA_TABLE_NAME = 0x1 -+ NFTA_TABLE_FLAGS = 0x2 -+ NFTA_TABLE_USE = 0x3 -+ NFTA_CHAIN_UNSPEC = 0x0 -+ NFTA_CHAIN_TABLE = 0x1 -+ NFTA_CHAIN_HANDLE = 0x2 -+ NFTA_CHAIN_NAME = 0x3 -+ NFTA_CHAIN_HOOK = 0x4 -+ NFTA_CHAIN_POLICY = 0x5 -+ NFTA_CHAIN_USE = 0x6 -+ NFTA_CHAIN_TYPE = 0x7 -+ NFTA_CHAIN_COUNTERS = 0x8 -+ NFTA_CHAIN_PAD = 0x9 -+ NFTA_RULE_UNSPEC = 0x0 -+ NFTA_RULE_TABLE = 0x1 -+ NFTA_RULE_CHAIN = 0x2 -+ NFTA_RULE_HANDLE = 0x3 -+ NFTA_RULE_EXPRESSIONS = 0x4 -+ NFTA_RULE_COMPAT = 0x5 -+ NFTA_RULE_POSITION = 0x6 -+ NFTA_RULE_USERDATA = 0x7 -+ NFTA_RULE_PAD = 0x8 -+ NFTA_RULE_ID = 0x9 -+ NFT_RULE_COMPAT_F_INV = 0x2 -+ NFT_RULE_COMPAT_F_MASK = 0x2 -+ NFTA_RULE_COMPAT_UNSPEC = 0x0 -+ NFTA_RULE_COMPAT_PROTO = 0x1 -+ NFTA_RULE_COMPAT_FLAGS = 0x2 -+ NFT_SET_ANONYMOUS = 0x1 -+ NFT_SET_CONSTANT = 0x2 -+ NFT_SET_INTERVAL = 0x4 -+ NFT_SET_MAP = 0x8 -+ NFT_SET_TIMEOUT = 0x10 -+ NFT_SET_EVAL = 0x20 -+ NFT_SET_OBJECT = 0x40 -+ NFT_SET_POL_PERFORMANCE = 0x0 -+ NFT_SET_POL_MEMORY = 0x1 -+ NFTA_SET_DESC_UNSPEC = 0x0 -+ NFTA_SET_DESC_SIZE = 0x1 -+ NFTA_SET_UNSPEC = 0x0 -+ NFTA_SET_TABLE = 0x1 -+ NFTA_SET_NAME = 0x2 -+ NFTA_SET_FLAGS = 0x3 -+ NFTA_SET_KEY_TYPE = 0x4 -+ NFTA_SET_KEY_LEN = 0x5 -+ NFTA_SET_DATA_TYPE = 0x6 -+ NFTA_SET_DATA_LEN = 0x7 -+ NFTA_SET_POLICY = 0x8 -+ NFTA_SET_DESC = 0x9 -+ NFTA_SET_ID = 0xa -+ NFTA_SET_TIMEOUT = 0xb -+ NFTA_SET_GC_INTERVAL = 0xc -+ NFTA_SET_USERDATA = 0xd -+ NFTA_SET_PAD = 0xe -+ NFTA_SET_OBJ_TYPE = 0xf -+ NFT_SET_ELEM_INTERVAL_END = 0x1 -+ NFTA_SET_ELEM_UNSPEC = 0x0 -+ NFTA_SET_ELEM_KEY = 0x1 -+ NFTA_SET_ELEM_DATA = 0x2 -+ NFTA_SET_ELEM_FLAGS = 0x3 -+ NFTA_SET_ELEM_TIMEOUT = 0x4 -+ NFTA_SET_ELEM_EXPIRATION = 0x5 -+ NFTA_SET_ELEM_USERDATA = 0x6 -+ NFTA_SET_ELEM_EXPR = 0x7 -+ NFTA_SET_ELEM_PAD = 0x8 -+ NFTA_SET_ELEM_OBJREF = 0x9 -+ NFTA_SET_ELEM_LIST_UNSPEC = 0x0 -+ NFTA_SET_ELEM_LIST_TABLE = 0x1 -+ NFTA_SET_ELEM_LIST_SET = 0x2 -+ NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 -+ NFTA_SET_ELEM_LIST_SET_ID = 0x4 -+ NFT_DATA_VALUE = 0x0 -+ NFT_DATA_VERDICT = 0xffffff00 -+ NFTA_DATA_UNSPEC = 0x0 -+ NFTA_DATA_VALUE = 0x1 -+ NFTA_DATA_VERDICT = 0x2 -+ NFTA_VERDICT_UNSPEC = 0x0 -+ NFTA_VERDICT_CODE = 0x1 -+ NFTA_VERDICT_CHAIN = 0x2 -+ NFTA_EXPR_UNSPEC = 0x0 -+ NFTA_EXPR_NAME = 0x1 -+ NFTA_EXPR_DATA = 0x2 -+ NFTA_IMMEDIATE_UNSPEC = 0x0 -+ NFTA_IMMEDIATE_DREG = 0x1 -+ NFTA_IMMEDIATE_DATA = 0x2 -+ NFTA_BITWISE_UNSPEC = 0x0 -+ NFTA_BITWISE_SREG = 0x1 -+ NFTA_BITWISE_DREG = 0x2 -+ NFTA_BITWISE_LEN = 0x3 -+ NFTA_BITWISE_MASK = 0x4 -+ NFTA_BITWISE_XOR = 0x5 -+ NFT_BYTEORDER_NTOH = 0x0 -+ NFT_BYTEORDER_HTON = 0x1 -+ NFTA_BYTEORDER_UNSPEC = 0x0 -+ NFTA_BYTEORDER_SREG = 0x1 -+ NFTA_BYTEORDER_DREG = 0x2 -+ NFTA_BYTEORDER_OP = 0x3 -+ NFTA_BYTEORDER_LEN = 0x4 -+ NFTA_BYTEORDER_SIZE = 0x5 -+ NFT_CMP_EQ = 0x0 -+ NFT_CMP_NEQ = 0x1 -+ NFT_CMP_LT = 0x2 -+ NFT_CMP_LTE = 0x3 -+ NFT_CMP_GT = 0x4 -+ NFT_CMP_GTE = 0x5 -+ NFTA_CMP_UNSPEC = 0x0 -+ NFTA_CMP_SREG = 0x1 -+ NFTA_CMP_OP = 0x2 -+ NFTA_CMP_DATA = 0x3 -+ NFT_RANGE_EQ = 0x0 -+ NFT_RANGE_NEQ = 0x1 -+ NFTA_RANGE_UNSPEC = 0x0 -+ NFTA_RANGE_SREG = 0x1 -+ NFTA_RANGE_OP = 0x2 -+ NFTA_RANGE_FROM_DATA = 0x3 -+ NFTA_RANGE_TO_DATA = 0x4 -+ NFT_LOOKUP_F_INV = 0x1 -+ NFTA_LOOKUP_UNSPEC = 0x0 -+ NFTA_LOOKUP_SET = 0x1 -+ NFTA_LOOKUP_SREG = 0x2 -+ NFTA_LOOKUP_DREG = 0x3 -+ NFTA_LOOKUP_SET_ID = 0x4 -+ NFTA_LOOKUP_FLAGS = 0x5 -+ NFT_DYNSET_OP_ADD = 0x0 -+ NFT_DYNSET_OP_UPDATE = 0x1 -+ NFT_DYNSET_F_INV = 0x1 -+ NFTA_DYNSET_UNSPEC = 0x0 -+ NFTA_DYNSET_SET_NAME = 0x1 -+ NFTA_DYNSET_SET_ID = 0x2 -+ NFTA_DYNSET_OP = 0x3 -+ NFTA_DYNSET_SREG_KEY = 0x4 -+ NFTA_DYNSET_SREG_DATA = 0x5 -+ NFTA_DYNSET_TIMEOUT = 0x6 -+ NFTA_DYNSET_EXPR = 0x7 -+ NFTA_DYNSET_PAD = 0x8 -+ NFTA_DYNSET_FLAGS = 0x9 -+ NFT_PAYLOAD_LL_HEADER = 0x0 -+ NFT_PAYLOAD_NETWORK_HEADER = 0x1 -+ NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 -+ NFT_PAYLOAD_CSUM_NONE = 0x0 -+ NFT_PAYLOAD_CSUM_INET = 0x1 -+ NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 -+ NFTA_PAYLOAD_UNSPEC = 0x0 -+ NFTA_PAYLOAD_DREG = 0x1 -+ NFTA_PAYLOAD_BASE = 0x2 -+ NFTA_PAYLOAD_OFFSET = 0x3 -+ NFTA_PAYLOAD_LEN = 0x4 -+ NFTA_PAYLOAD_SREG = 0x5 -+ NFTA_PAYLOAD_CSUM_TYPE = 0x6 -+ NFTA_PAYLOAD_CSUM_OFFSET = 0x7 -+ NFTA_PAYLOAD_CSUM_FLAGS = 0x8 -+ NFT_EXTHDR_F_PRESENT = 0x1 -+ NFT_EXTHDR_OP_IPV6 = 0x0 -+ NFT_EXTHDR_OP_TCPOPT = 0x1 -+ NFTA_EXTHDR_UNSPEC = 0x0 -+ NFTA_EXTHDR_DREG = 0x1 -+ NFTA_EXTHDR_TYPE = 0x2 -+ NFTA_EXTHDR_OFFSET = 0x3 -+ NFTA_EXTHDR_LEN = 0x4 -+ NFTA_EXTHDR_FLAGS = 0x5 -+ NFTA_EXTHDR_OP = 0x6 -+ NFTA_EXTHDR_SREG = 0x7 -+ NFT_META_LEN = 0x0 -+ NFT_META_PROTOCOL = 0x1 -+ NFT_META_PRIORITY = 0x2 -+ NFT_META_MARK = 0x3 -+ NFT_META_IIF = 0x4 -+ NFT_META_OIF = 0x5 -+ NFT_META_IIFNAME = 0x6 -+ NFT_META_OIFNAME = 0x7 -+ NFT_META_IIFTYPE = 0x8 -+ NFT_META_OIFTYPE = 0x9 -+ NFT_META_SKUID = 0xa -+ NFT_META_SKGID = 0xb -+ NFT_META_NFTRACE = 0xc -+ NFT_META_RTCLASSID = 0xd -+ NFT_META_SECMARK = 0xe -+ NFT_META_NFPROTO = 0xf -+ NFT_META_L4PROTO = 0x10 -+ NFT_META_BRI_IIFNAME = 0x11 -+ NFT_META_BRI_OIFNAME = 0x12 -+ NFT_META_PKTTYPE = 0x13 -+ NFT_META_CPU = 0x14 -+ NFT_META_IIFGROUP = 0x15 -+ NFT_META_OIFGROUP = 0x16 -+ NFT_META_CGROUP = 0x17 -+ NFT_META_PRANDOM = 0x18 -+ NFT_RT_CLASSID = 0x0 -+ NFT_RT_NEXTHOP4 = 0x1 -+ NFT_RT_NEXTHOP6 = 0x2 -+ NFT_RT_TCPMSS = 0x3 -+ NFT_HASH_JENKINS = 0x0 -+ NFT_HASH_SYM = 0x1 -+ NFTA_HASH_UNSPEC = 0x0 -+ NFTA_HASH_SREG = 0x1 -+ NFTA_HASH_DREG = 0x2 -+ NFTA_HASH_LEN = 0x3 -+ NFTA_HASH_MODULUS = 0x4 -+ NFTA_HASH_SEED = 0x5 -+ NFTA_HASH_OFFSET = 0x6 -+ NFTA_HASH_TYPE = 0x7 -+ NFTA_META_UNSPEC = 0x0 -+ NFTA_META_DREG = 0x1 -+ NFTA_META_KEY = 0x2 -+ NFTA_META_SREG = 0x3 -+ NFTA_RT_UNSPEC = 0x0 -+ NFTA_RT_DREG = 0x1 -+ NFTA_RT_KEY = 0x2 -+ NFT_CT_STATE = 0x0 -+ NFT_CT_DIRECTION = 0x1 -+ NFT_CT_STATUS = 0x2 -+ NFT_CT_MARK = 0x3 -+ NFT_CT_SECMARK = 0x4 -+ NFT_CT_EXPIRATION = 0x5 -+ NFT_CT_HELPER = 0x6 -+ NFT_CT_L3PROTOCOL = 0x7 -+ NFT_CT_SRC = 0x8 -+ NFT_CT_DST = 0x9 -+ NFT_CT_PROTOCOL = 0xa -+ NFT_CT_PROTO_SRC = 0xb -+ NFT_CT_PROTO_DST = 0xc -+ NFT_CT_LABELS = 0xd -+ NFT_CT_PKTS = 0xe -+ NFT_CT_BYTES = 0xf -+ NFT_CT_AVGPKT = 0x10 -+ NFT_CT_ZONE = 0x11 -+ NFT_CT_EVENTMASK = 0x12 -+ NFTA_CT_UNSPEC = 0x0 -+ NFTA_CT_DREG = 0x1 -+ NFTA_CT_KEY = 0x2 -+ NFTA_CT_DIRECTION = 0x3 -+ NFTA_CT_SREG = 0x4 -+ NFT_LIMIT_PKTS = 0x0 -+ NFT_LIMIT_PKT_BYTES = 0x1 -+ NFT_LIMIT_F_INV = 0x1 -+ NFTA_LIMIT_UNSPEC = 0x0 -+ NFTA_LIMIT_RATE = 0x1 -+ NFTA_LIMIT_UNIT = 0x2 -+ NFTA_LIMIT_BURST = 0x3 -+ NFTA_LIMIT_TYPE = 0x4 -+ NFTA_LIMIT_FLAGS = 0x5 -+ NFTA_LIMIT_PAD = 0x6 -+ NFTA_COUNTER_UNSPEC = 0x0 -+ NFTA_COUNTER_BYTES = 0x1 -+ NFTA_COUNTER_PACKETS = 0x2 -+ NFTA_COUNTER_PAD = 0x3 -+ NFTA_LOG_UNSPEC = 0x0 -+ NFTA_LOG_GROUP = 0x1 -+ NFTA_LOG_PREFIX = 0x2 -+ NFTA_LOG_SNAPLEN = 0x3 -+ NFTA_LOG_QTHRESHOLD = 0x4 -+ NFTA_LOG_LEVEL = 0x5 -+ NFTA_LOG_FLAGS = 0x6 -+ NFTA_QUEUE_UNSPEC = 0x0 -+ NFTA_QUEUE_NUM = 0x1 -+ NFTA_QUEUE_TOTAL = 0x2 -+ NFTA_QUEUE_FLAGS = 0x3 -+ NFTA_QUEUE_SREG_QNUM = 0x4 -+ NFT_QUOTA_F_INV = 0x1 -+ NFT_QUOTA_F_DEPLETED = 0x2 -+ NFTA_QUOTA_UNSPEC = 0x0 -+ NFTA_QUOTA_BYTES = 0x1 -+ NFTA_QUOTA_FLAGS = 0x2 -+ NFTA_QUOTA_PAD = 0x3 -+ NFTA_QUOTA_CONSUMED = 0x4 -+ NFT_REJECT_ICMP_UNREACH = 0x0 -+ NFT_REJECT_TCP_RST = 0x1 -+ NFT_REJECT_ICMPX_UNREACH = 0x2 -+ NFT_REJECT_ICMPX_NO_ROUTE = 0x0 -+ NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 -+ NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 -+ NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 -+ NFTA_REJECT_UNSPEC = 0x0 -+ NFTA_REJECT_TYPE = 0x1 -+ NFTA_REJECT_ICMP_CODE = 0x2 -+ NFT_NAT_SNAT = 0x0 -+ NFT_NAT_DNAT = 0x1 -+ NFTA_NAT_UNSPEC = 0x0 -+ NFTA_NAT_TYPE = 0x1 -+ NFTA_NAT_FAMILY = 0x2 -+ NFTA_NAT_REG_ADDR_MIN = 0x3 -+ NFTA_NAT_REG_ADDR_MAX = 0x4 -+ NFTA_NAT_REG_PROTO_MIN = 0x5 -+ NFTA_NAT_REG_PROTO_MAX = 0x6 -+ NFTA_NAT_FLAGS = 0x7 -+ NFTA_MASQ_UNSPEC = 0x0 -+ NFTA_MASQ_FLAGS = 0x1 -+ NFTA_MASQ_REG_PROTO_MIN = 0x2 -+ NFTA_MASQ_REG_PROTO_MAX = 0x3 -+ NFTA_REDIR_UNSPEC = 0x0 -+ NFTA_REDIR_REG_PROTO_MIN = 0x1 -+ NFTA_REDIR_REG_PROTO_MAX = 0x2 -+ NFTA_REDIR_FLAGS = 0x3 -+ NFTA_DUP_UNSPEC = 0x0 -+ NFTA_DUP_SREG_ADDR = 0x1 -+ NFTA_DUP_SREG_DEV = 0x2 -+ NFTA_FWD_UNSPEC = 0x0 -+ NFTA_FWD_SREG_DEV = 0x1 -+ NFTA_OBJREF_UNSPEC = 0x0 -+ NFTA_OBJREF_IMM_TYPE = 0x1 -+ NFTA_OBJREF_IMM_NAME = 0x2 -+ NFTA_OBJREF_SET_SREG = 0x3 -+ NFTA_OBJREF_SET_NAME = 0x4 -+ NFTA_OBJREF_SET_ID = 0x5 -+ NFTA_GEN_UNSPEC = 0x0 -+ NFTA_GEN_ID = 0x1 -+ NFTA_GEN_PROC_PID = 0x2 -+ NFTA_GEN_PROC_NAME = 0x3 -+ NFTA_FIB_UNSPEC = 0x0 -+ NFTA_FIB_DREG = 0x1 -+ NFTA_FIB_RESULT = 0x2 -+ NFTA_FIB_FLAGS = 0x3 -+ NFT_FIB_RESULT_UNSPEC = 0x0 -+ NFT_FIB_RESULT_OIF = 0x1 -+ NFT_FIB_RESULT_OIFNAME = 0x2 -+ NFT_FIB_RESULT_ADDRTYPE = 0x3 -+ NFTA_FIB_F_SADDR = 0x1 -+ NFTA_FIB_F_DADDR = 0x2 -+ NFTA_FIB_F_MARK = 0x4 -+ NFTA_FIB_F_IIF = 0x8 -+ NFTA_FIB_F_OIF = 0x10 -+ NFTA_FIB_F_PRESENT = 0x20 -+ NFTA_CT_HELPER_UNSPEC = 0x0 -+ NFTA_CT_HELPER_NAME = 0x1 -+ NFTA_CT_HELPER_L3PROTO = 0x2 -+ NFTA_CT_HELPER_L4PROTO = 0x3 -+ NFTA_OBJ_UNSPEC = 0x0 -+ NFTA_OBJ_TABLE = 0x1 -+ NFTA_OBJ_NAME = 0x2 -+ NFTA_OBJ_TYPE = 0x3 -+ NFTA_OBJ_DATA = 0x4 -+ NFTA_OBJ_USE = 0x5 -+ NFTA_TRACE_UNSPEC = 0x0 -+ NFTA_TRACE_TABLE = 0x1 -+ NFTA_TRACE_CHAIN = 0x2 -+ NFTA_TRACE_RULE_HANDLE = 0x3 -+ NFTA_TRACE_TYPE = 0x4 -+ NFTA_TRACE_VERDICT = 0x5 -+ NFTA_TRACE_ID = 0x6 -+ NFTA_TRACE_LL_HEADER = 0x7 -+ NFTA_TRACE_NETWORK_HEADER = 0x8 -+ NFTA_TRACE_TRANSPORT_HEADER = 0x9 -+ NFTA_TRACE_IIF = 0xa -+ NFTA_TRACE_IIFTYPE = 0xb -+ NFTA_TRACE_OIF = 0xc -+ NFTA_TRACE_OIFTYPE = 0xd -+ NFTA_TRACE_MARK = 0xe -+ NFTA_TRACE_NFPROTO = 0xf -+ NFTA_TRACE_POLICY = 0x10 -+ NFTA_TRACE_PAD = 0x11 -+ NFT_TRACETYPE_UNSPEC = 0x0 -+ NFT_TRACETYPE_POLICY = 0x1 -+ NFT_TRACETYPE_RETURN = 0x2 -+ NFT_TRACETYPE_RULE = 0x3 -+ NFTA_NG_UNSPEC = 0x0 -+ NFTA_NG_DREG = 0x1 -+ NFTA_NG_MODULUS = 0x2 -+ NFTA_NG_TYPE = 0x3 -+ NFTA_NG_OFFSET = 0x4 -+ NFT_NG_INCREMENTAL = 0x0 -+ NFT_NG_RANDOM = 0x1 -+) -+ -+type RTCTime struct { -+ Sec int32 -+ Min int32 -+ Hour int32 -+ Mday int32 -+ Mon int32 -+ Year int32 -+ Wday int32 -+ Yday int32 -+ Isdst int32 -+} -+ -+type RTCWkAlrm struct { -+ Enabled uint8 -+ Pending uint8 -+ Time RTCTime -+} -+ -+type RTCPLLInfo struct { -+ Ctrl int32 -+ Value int32 -+ Max int32 -+ Min int32 -+ Posmult int32 -+ Negmult int32 -+ Clock int64 -+} -+ -+type BlkpgIoctlArg struct { -+ Op int32 -+ Flags int32 -+ Datalen int32 -+ Data *byte -+} -+ -+type BlkpgPartition struct { -+ Start int64 -+ Length int64 -+ Pno int32 -+ Devname [64]uint8 -+ Volname [64]uint8 -+ _ [4]byte -+} -+ -+const ( -+ BLKPG = 0x1269 -+ BLKPG_ADD_PARTITION = 0x1 -+ BLKPG_DEL_PARTITION = 0x2 -+ BLKPG_RESIZE_PARTITION = 0x3 -+) -+ -+const ( -+ NETNSA_NONE = 0x0 -+ NETNSA_NSID = 0x1 -+ NETNSA_PID = 0x2 -+ NETNSA_FD = 0x3 -+) -+ -+type XDPRingOffset struct { -+ Producer uint64 -+ Consumer uint64 -+ Desc uint64 -+} -+ -+type XDPMmapOffsets struct { -+ Rx XDPRingOffset -+ Tx XDPRingOffset -+ Fr XDPRingOffset -+ Cr XDPRingOffset -+} -+ -+type XDPUmemReg struct { -+ Addr uint64 -+ Len uint64 -+ Size uint32 -+ Headroom uint32 -+} -+ -+type XDPStatistics struct { -+ Rx_dropped uint64 -+ Rx_invalid_descs uint64 -+ Tx_invalid_descs uint64 -+} -+ -+type XDPDesc struct { -+ Addr uint64 -+ Len uint32 -+ Options uint32 -+} -+ -+const ( -+ NCSI_CMD_UNSPEC = 0x0 -+ NCSI_CMD_PKG_INFO = 0x1 -+ NCSI_CMD_SET_INTERFACE = 0x2 -+ NCSI_CMD_CLEAR_INTERFACE = 0x3 -+ NCSI_ATTR_UNSPEC = 0x0 -+ NCSI_ATTR_IFINDEX = 0x1 -+ NCSI_ATTR_PACKAGE_LIST = 0x2 -+ NCSI_ATTR_PACKAGE_ID = 0x3 -+ NCSI_ATTR_CHANNEL_ID = 0x4 -+ NCSI_PKG_ATTR_UNSPEC = 0x0 -+ NCSI_PKG_ATTR = 0x1 -+ NCSI_PKG_ATTR_ID = 0x2 -+ NCSI_PKG_ATTR_FORCED = 0x3 -+ NCSI_PKG_ATTR_CHANNEL_LIST = 0x4 -+ NCSI_CHANNEL_ATTR_UNSPEC = 0x0 -+ NCSI_CHANNEL_ATTR = 0x1 -+ NCSI_CHANNEL_ATTR_ID = 0x2 -+ NCSI_CHANNEL_ATTR_VERSION_MAJOR = 0x3 -+ NCSI_CHANNEL_ATTR_VERSION_MINOR = 0x4 -+ NCSI_CHANNEL_ATTR_VERSION_STR = 0x5 -+ NCSI_CHANNEL_ATTR_LINK_STATE = 0x6 -+ NCSI_CHANNEL_ATTR_ACTIVE = 0x7 -+ NCSI_CHANNEL_ATTR_FORCED = 0x8 -+ NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9 -+ NCSI_CHANNEL_ATTR_VLAN_ID = 0xa -+) -+ -+type ScmTimestamping struct { -+ Ts [3]Timespec -+} -+ -+const ( -+ SOF_TIMESTAMPING_TX_HARDWARE = 0x1 -+ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 -+ SOF_TIMESTAMPING_RX_HARDWARE = 0x4 -+ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8 -+ SOF_TIMESTAMPING_SOFTWARE = 0x10 -+ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20 -+ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40 -+ SOF_TIMESTAMPING_OPT_ID = 0x80 -+ SOF_TIMESTAMPING_TX_SCHED = 0x100 -+ SOF_TIMESTAMPING_TX_ACK = 0x200 -+ SOF_TIMESTAMPING_OPT_CMSG = 0x400 -+ SOF_TIMESTAMPING_OPT_TSONLY = 0x800 -+ SOF_TIMESTAMPING_OPT_STATS = 0x1000 -+ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000 -+ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000 -+ -+ SOF_TIMESTAMPING_LAST = 0x4000 -+ SOF_TIMESTAMPING_MASK = 0x7fff -+ -+ SCM_TSTAMP_SND = 0x0 -+ SCM_TSTAMP_SCHED = 0x1 -+ SCM_TSTAMP_ACK = 0x2 -+) -+ -+type SockExtendedErr struct { -+ Errno uint32 -+ Origin uint8 -+ Type uint8 -+ Code uint8 -+ Pad uint8 -+ Info uint32 -+ Data uint32 -+} --- -2.23.0 - diff --git a/patch/0177-resume-suspend-dm-on-start.patch b/patch/0177-resume-suspend-dm-on-start.patch deleted file mode 100644 index 2ee80f3..0000000 --- a/patch/0177-resume-suspend-dm-on-start.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 37e3e3dfb31f30b2599d05f021671f6e682f37d6 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 9 Dec 2020 17:37:02 +0800 -Subject: [PATCH] resume suspend dm on start - -Change-Id: Ibe215c80aa62b4d4b464749cc6e995d2e0e845af -Signed-off-by: jingrui ---- - components/engine/cmd/dockerd/daemon.go | 43 +++++++++++++++++++++++++ - 1 file changed, 43 insertions(+) - -diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go -index 0b3fa0e037..dbf37f3338 100644 ---- a/components/engine/cmd/dockerd/daemon.go -+++ b/components/engine/cmd/dockerd/daemon.go -@@ -6,6 +6,7 @@ import ( - "fmt" - "io/ioutil" - "os" -+ "os/exec" - "path/filepath" - "runtime" - "strings" -@@ -72,6 +73,45 @@ func NewDaemonCli() *DaemonCli { - return &DaemonCli{} - } - -+func resumeDM() { -+ c := make(chan struct{}) -+ go func() { -+ defer close(c) -+ out, err := exec.Command("dmsetup", "info", "-c", "--sort", "minor", "--noheadings", "--separator", ",", "-o", "attr,name").CombinedOutput() -+ if err != nil { -+ logrus.Errorf("resume-dm dmsetup info failed: %v", err) -+ return -+ } -+ -+ args := []string{"resume"} -+ for _, line := range strings.Split(string(out), "\n") { -+ aa := strings.Split(line, ",") -+ if len(aa) != 2 || !strings.Contains(aa[0], "s") || strings.Index(aa[1], "docker-") != 0 { -+ continue -+ } -+ args = append(args, aa[1]) -+ } -+ if len(args) == 1 { -+ return -+ } -+ -+ logrus.Infof("resume-dm start resume suspended dm %v", args) -+ _, err = exec.Command("dmsetup", args...).CombinedOutput() -+ if err != nil { -+ logrus.Errorf("resume-dm %s failed: %v", err) -+ return -+ } -+ logrus.Infof("resume-dm finished resume suspended dm") -+ }() -+ select { -+ case <-c: -+ return -+ case <-time.After(10*time.Second): -+ logrus.Warnf("resume-dm timeout, continue anyway.") -+ return -+ } -+} -+ - func cleanupLocalDB(db string) { - _, err := os.Stat(db) - if err == nil { -@@ -150,6 +190,9 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { - }) - - system.InitLCOW(cli.Config.Experimental) -+ if cli.Config.GraphDriver == "devicemapper" { -+ resumeDM() -+ } - - if err := setDefaultUmask(); err != nil { - return fmt.Errorf("Failed to set umask: %v", err) --- -2.17.1 - diff --git a/patch/0178-docker-skip-kill-and-restart-containerd-during-docke.patch b/patch/0178-docker-skip-kill-and-restart-containerd-during-docke.patch deleted file mode 100644 index 69d9794..0000000 --- a/patch/0178-docker-skip-kill-and-restart-containerd-during-docke.patch +++ /dev/null @@ -1,85 +0,0 @@ -From a56def385f835885df056d0d54372111abdc1507 Mon Sep 17 00:00:00 2001 -From: xiadanni -Date: Sat, 19 Dec 2020 18:56:38 +0800 -Subject: [PATCH] docker:skip kill and restart containerd during docker daemon - is starting - -Signed-off-by: xiadanni ---- - components/engine/cmd/dockerd/daemon.go | 4 +++- - components/engine/libcontainerd/supervisor/remote_daemon.go | 9 +++++++++ - 2 files changed, 12 insertions(+), 1 deletion(-) - -diff --git a/components/engine/cmd/dockerd/daemon.go b/components/engine/cmd/dockerd/daemon.go -index dbf37f3..c25ee0e 100644 ---- a/components/engine/cmd/dockerd/daemon.go -+++ b/components/engine/cmd/dockerd/daemon.go -@@ -10,6 +10,7 @@ import ( - "path/filepath" - "runtime" - "strings" -+ "sync/atomic" - "time" - - containerddefaults "github.com/containerd/containerd/defaults" -@@ -106,7 +107,7 @@ func resumeDM() { - select { - case <-c: - return -- case <-time.After(10*time.Second): -+ case <-time.After(10 * time.Second): - logrus.Warnf("resume-dm timeout, continue anyway.") - return - } -@@ -304,6 +305,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) { - - logrus.Info("Daemon has completed initialization") - -+ atomic.StoreInt32(&supervisor.IsDockerUp, 1) - cli.d = d - - routerOptions, err := newRouterOptions(cli.Config, d) -diff --git a/components/engine/libcontainerd/supervisor/remote_daemon.go b/components/engine/libcontainerd/supervisor/remote_daemon.go -index 62ea58c..19582cd 100644 ---- a/components/engine/libcontainerd/supervisor/remote_daemon.go -+++ b/components/engine/libcontainerd/supervisor/remote_daemon.go -@@ -11,6 +11,7 @@ import ( - "strconv" - "strings" - "sync" -+ "sync/atomic" - "time" - - "github.com/BurntSushi/toml" -@@ -19,6 +20,7 @@ import ( - "github.com/docker/docker/pkg/system" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" -+ "golang.org/x/sys/unix" - ) - - const ( -@@ -31,6 +33,8 @@ const ( - pidFile = "containerd.pid" - ) - -+var IsDockerUp int32 -+ - type pluginConfigs struct { - Plugins map[string]interface{} `toml:"plugins"` - } -@@ -314,6 +318,11 @@ func (r *remote) monitorDaemon(ctx context.Context) { - } - - if system.IsProcessAlive(r.daemonPid) { -+ if atomic.LoadInt32(&IsDockerUp) == 0 { -+ r.logger.WithField("pid", r.daemonPid).Info("dockerd is starting, skip killing containerd") -+ unix.Kill(r.daemonPid, unix.SIGCONT) -+ continue -+ } - r.logger.WithField("pid", r.daemonPid).Info("killing and restarting containerd") - r.killDaemon() - } --- -1.8.3.1 - diff --git a/patch/0179-handle-exit-force.patch b/patch/0179-handle-exit-force.patch deleted file mode 100644 index 76c1a5e..0000000 --- a/patch/0179-handle-exit-force.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 66b6e3065b160bd7d480f183156acbe1cb9bf2e0 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Tue, 15 Dec 2020 16:05:56 +0800 -Subject: [PATCH] handle exit force - -Change-Id: If08483f57b4f04d6c4961c9f588e4d599009eddc -Signed-off-by: jingrui ---- - components/engine/daemon/monitor.go | 9 +++++++++ - components/engine/libcontainerd/client_daemon.go | 14 ++++++++++++++ - components/engine/libcontainerd/types.go | 1 + - .../plugin/executor/containerd/containerd.go | 5 +++++ - 4 files changed, 29 insertions(+) - -diff --git a/components/engine/daemon/monitor.go b/components/engine/daemon/monitor.go -index e041bd5c69..1b577c0dae 100644 ---- a/components/engine/daemon/monitor.go -+++ b/components/engine/daemon/monitor.go -@@ -26,6 +26,14 @@ func (daemon *Daemon) setStateCounter(c *container.Container) { - } - } - -+func (daemon *Daemon) IsContainerRunning(id string) bool { -+ c, err := daemon.GetContainer(id) -+ if err != nil { -+ return false -+ } -+ return c.IsRunning() -+} -+ - // ProcessEvent is called by libcontainerd whenever an event occurs - func (daemon *Daemon) ProcessEvent(id string, e libcontainerd.EventType, ei libcontainerd.EventInfo) error { - c, err := daemon.GetContainer(id) -@@ -51,6 +59,7 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerd.EventType, ei libc - case libcontainerd.EventExit: - if int(ei.Pid) == c.Pid { - c.Lock() -+ logrus.Infof("handle exit event cid=%s pid=%d", c.ID, c.Pid) - _, _, err := daemon.containerd.DeleteTask(context.Background(), c.ID) - if err != nil { - logrus.WithError(err).Warnf("failed to delete container %s from containerd", c.ID) -diff --git a/components/engine/libcontainerd/client_daemon.go b/components/engine/libcontainerd/client_daemon.go -index 05c439c540..502796bd25 100755 ---- a/components/engine/libcontainerd/client_daemon.go -+++ b/components/engine/libcontainerd/client_daemon.go -@@ -517,9 +517,16 @@ func (c *client) DeleteTask(ctx context.Context, containerID string) (uint32, ti - return status.ExitCode(), status.ExitTime(), nil - } - -+func (c *client) deleteForce(ctx context.Context, id string) { -+ if ctr, err := c.client.LoadContainer(ctx, id); err == nil { -+ logrus.Warnf("delete containerd meta id=%s force: error=%v", id, ctr.Delete(ctx)) -+ } -+} -+ - func (c *client) Delete(ctx context.Context, containerID string) error { - ctr := c.getContainer(containerID) - if ctr == nil { -+ c.deleteForce(ctx, containerID) - return errors.WithStack(newNotFoundError("no such container")) - } - -@@ -907,6 +914,13 @@ func (c *client) processEventStream(ctx context.Context, ns string) { - ctr = c.getContainer(ei.ContainerID) - if ctr == nil { - c.logger.WithField("container", ei.ContainerID).Warn("unknown container") -+ if et == EventExit && ei.ProcessID == ei.ContainerID && c.backend.IsContainerRunning(ei.ContainerID) { -+ c.logger.WithField("container", ei.ContainerID).Warn("handle exit event force ...") -+ c.eventQ.append(ei.ContainerID, func() { -+ c.logger.WithField("container", ei.ContainerID).Warnf("handle exit event force: error=%v", -+ c.backend.ProcessEvent(ei.ContainerID, et, ei)) -+ }) -+ } - continue - } - -diff --git a/components/engine/libcontainerd/types.go b/components/engine/libcontainerd/types.go -index c4de5e674d..0b9df9193b 100644 ---- a/components/engine/libcontainerd/types.go -+++ b/components/engine/libcontainerd/types.go -@@ -60,6 +60,7 @@ type EventInfo struct { - // Backend defines callbacks that the client of the library needs to implement. - type Backend interface { - ProcessEvent(containerID string, event EventType, ei EventInfo) error -+ IsContainerRunning(id string) bool - } - - // Client provides access to containerd features. -diff --git a/components/engine/plugin/executor/containerd/containerd.go b/components/engine/plugin/executor/containerd/containerd.go -index a3401dce79..f75771fe41 100644 ---- a/components/engine/plugin/executor/containerd/containerd.go -+++ b/components/engine/plugin/executor/containerd/containerd.go -@@ -141,6 +141,11 @@ func (e *Executor) ProcessEvent(id string, et libcontainerd.EventType, ei libcon - return nil - } - -+func (e *Executor) IsContainerRunning(id string) bool { -+ ok, _ := e.IsRunning(id) -+ return ok -+} -+ - type rio struct { - cio.IO - --- -2.17.1 - diff --git a/patch/0180-wait-io-with-timeout-in-task-delete.patch b/patch/0180-wait-io-with-timeout-in-task-delete.patch deleted file mode 100644 index 5ac8675..0000000 --- a/patch/0180-wait-io-with-timeout-in-task-delete.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0f3aa35a1c38fe7fc49cd6fb66fc47a993ad6bb8 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 16 Dec 2020 18:39:00 +0800 -Subject: [PATCH] wait io with timeout in task delete - -Change-Id: I23ed40d69279b14a216b6ffb9988439475be5cad -Signed-off-by: jingrui ---- - .../github.com/containerd/containerd/task.go | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - -diff --git a/components/engine/vendor/github.com/containerd/containerd/task.go b/components/engine/vendor/github.com/containerd/containerd/task.go -index 6806e11620..7421432bed 100644 ---- a/components/engine/vendor/github.com/containerd/containerd/task.go -+++ b/components/engine/vendor/github.com/containerd/containerd/task.go -@@ -44,6 +44,7 @@ import ( - "github.com/opencontainers/image-spec/specs-go/v1" - specs "github.com/opencontainers/runtime-spec/specs-go" - "github.com/pkg/errors" -+ "github.com/sirupsen/logrus" - ) - - // UnknownExitStatus is returned when containerd is unable to -@@ -287,8 +288,18 @@ func (t *task) Delete(ctx context.Context, opts ...ProcessDeleteOpts) (*ExitStat - return nil, errors.Wrapf(errdefs.ErrFailedPrecondition, "task must be stopped before deletion: %s", status.Status) - } - if t.io != nil { -- t.io.Cancel() -- t.io.Wait() -+ done := make(chan struct{}) -+ go func() { -+ t.io.Cancel() -+ t.io.Wait() -+ close(done) -+ }() -+ select { -+ case <-time.After(3 * time.Second): -+ logrus.Warnf("task delete wait io close timeout, some fifo io may be dropped.") -+ case <-done: -+ // ok -+ } - } - r, err := t.client.TaskService().Delete(ctx, &tasks.DeleteTaskRequest{ - ContainerID: t.id, --- -2.17.1 - diff --git a/patch/0181-docker-do-not-return-when-matched-registry-mirror.patch b/patch/0181-docker-do-not-return-when-matched-registry-mirror.patch deleted file mode 100644 index 54b67f3..0000000 --- a/patch/0181-docker-do-not-return-when-matched-registry-mirror.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 8cc3f33020152d51d38927593ba49ad3dfacf62e Mon Sep 17 00:00:00 2001 -From: shaobao.feng -Date: Mon, 7 Dec 2020 15:30:11 +0800 -Subject: [PATCH] docker: do not return when matched registry mirror - -Change-Id: I5317b91b60293e1f4c50f5a327790c5509537f9b -reason: append hostname itself to make sure the hostname itself will be tried. ---- - components/engine/registry/service_v2.go | 86 +++++++++++------------- - 1 file changed, 41 insertions(+), 45 deletions(-) - -diff --git a/components/engine/registry/service_v2.go b/components/engine/registry/service_v2.go -index adeb10c550..df66cd7451 100644 ---- a/components/engine/registry/service_v2.go -+++ b/components/engine/registry/service_v2.go -@@ -19,8 +19,7 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp - if reg != nil { - var regEndpoints []registrytypes.Endpoint = reg.Mirrors - -- lastIndex := len(regEndpoints) - 1 -- for i, regEP := range regEndpoints { -+ for _, regEP := range regEndpoints { - official := regEP.Address == registrytypes.DefaultEndpoint.Address - regURL := regEP.GetURL() - -@@ -41,49 +40,48 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp - TLSConfig: tlsConfig, - Prefix: hostname, - // the last endpoint is not considered a mirror -- Mirror: i != lastIndex, -+ Mirror: true, - }) - } -- return endpoints, nil -+ // don't return here, otherwise the hostname itself will not be appended to the endpoints, -+ // and the hostname itself will not be tried, which is not a desired action. - } -- } else { -+ } -+ if hostname == DefaultNamespace || hostname == IndexHostname { - tlsConfig = tlsconfig.ServerDefault() -- if hostname == DefaultNamespace || hostname == IndexHostname { -- // v2 mirrors -- for _, mirror := range s.config.Mirrors { -- if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") { -- mirror = "https://" + mirror -- } -- mirrorURL, err := url.Parse(mirror) -- if err != nil { -- return nil, err -- } -- mirrorTLSConfig, err := s.tlsConfigForMirror(mirrorURL) -- if err != nil { -- return nil, err -- } -- endpoints = append(endpoints, APIEndpoint{ -- URL: mirrorURL, -- // guess mirrors are v2 -- Version: APIVersion2, -- Mirror: true, -- TrimHostname: true, -- TLSConfig: mirrorTLSConfig, -- }) -+ // v2 mirrors -+ for _, mirror := range s.config.Mirrors { -+ if !strings.HasPrefix(mirror, "http://") && !strings.HasPrefix(mirror, "https://") { -+ mirror = "https://" + mirror -+ } -+ mirrorURL, err := url.Parse(mirror) -+ if err != nil { -+ return nil, err -+ } -+ mirrorTLSConfig, err := s.tlsConfigForMirror(mirrorURL) -+ if err != nil { -+ return nil, err - } -- // v2 registry - endpoints = append(endpoints, APIEndpoint{ -- URL: DefaultV2Registry, -+ URL: mirrorURL, -+ // guess mirrors are v2 - Version: APIVersion2, -- Official: true, -+ Mirror: true, - TrimHostname: true, -- TLSConfig: tlsConfig, -+ TLSConfig: mirrorTLSConfig, - }) -- -- return endpoints, nil - } -- } -+ // v2 registry -+ endpoints = append(endpoints, APIEndpoint{ -+ URL: DefaultV2Registry, -+ Version: APIVersion2, -+ Official: true, -+ TrimHostname: true, -+ TLSConfig: tlsConfig, -+ }) - -+ return endpoints, nil -+ } - ana := allowNondistributableArtifacts(s.config, hostname) - - tlsConfig, err = s.tlsConfig(hostname) -@@ -91,18 +89,16 @@ func (s *DefaultService) lookupV2Endpoints(hostname string) (endpoints []APIEndp - return nil, err - } - -- endpoints = []APIEndpoint{ -- { -- URL: &url.URL{ -- Scheme: "https", -- Host: hostname, -- }, -- Version: APIVersion2, -- AllowNondistributableArtifacts: ana, -- TrimHostname: true, -- TLSConfig: tlsConfig, -+ endpoints = append(endpoints, APIEndpoint{ -+ URL: &url.URL{ -+ Scheme: "https", -+ Host: hostname, - }, -- } -+ Version: APIVersion2, -+ AllowNondistributableArtifacts: ana, -+ TrimHostname: true, -+ TLSConfig: tlsConfig, -+ }) - - if tlsConfig.InsecureSkipVerify { - endpoints = append(endpoints, APIEndpoint{ --- -2.17.1 - diff --git a/patch/0183-add-masked-paths-pagealloc_module-and-slaballoc_stat.patch b/patch/0183-add-masked-paths-pagealloc_module-and-slaballoc_stat.patch deleted file mode 100644 index 5ed2ef1..0000000 --- a/patch/0183-add-masked-paths-pagealloc_module-and-slaballoc_stat.patch +++ /dev/null @@ -1,29 +0,0 @@ -From fada5f66fcc555d706603dd3c7832e78e9955501 Mon Sep 17 00:00:00 2001 -From: liuzekun -Date: Thu, 31 Dec 2020 03:07:42 -0500 -Subject: add masked paths pagealloc_module and slaballoc_statistics - -Signed-off-by: liuzekun ---- - components/engine/oci/defaults.go | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/components/engine/oci/defaults.go b/components/engine/oci/defaults.go -index e763cb75..ff027d89 100644 ---- a/components/engine/oci/defaults.go -+++ b/components/engine/oci/defaults.go -@@ -135,9 +135,11 @@ func DefaultLinuxSpec() specs.Spec { - "/proc/oom_extend", - "/proc/pagealloc_statistics", - "/proc/pagealloc_bt", -+ "/proc/pagealloc_module", - "/proc/pin_memory", - "/proc/slaballoc_bt", - "/proc/slaballoc_module", -+ "/proc/slaballoc_statistics", - "/proc/sched_debug", - "/proc/scsi", - "/proc/sig_catch", --- -2.19.1 - diff --git a/patch/0184-docker-wait-io-with-timeout-when-process-Start-faile.patch b/patch/0184-docker-wait-io-with-timeout-when-process-Start-faile.patch deleted file mode 100644 index c9784dc..0000000 --- a/patch/0184-docker-wait-io-with-timeout-when-process-Start-faile.patch +++ /dev/null @@ -1,48 +0,0 @@ -From ef64f4dd5d532b550bb68f60e6373e139fdf5382 Mon Sep 17 00:00:00 2001 -From: xiadanni -Date: Fri, 15 Jan 2021 11:23:04 +0800 -Subject: [PATCH] docker: wait io with timeout when process Start failed - -Signed-off-by: xiadanni ---- - .../vendor/github.com/containerd/containerd/process.go | 17 ++++++++++++++--- - 1 file changed, 14 insertions(+), 3 deletions(-) - -diff --git a/components/engine/vendor/github.com/containerd/containerd/process.go b/components/engine/vendor/github.com/containerd/containerd/process.go -index ff7d838..4d0dca9 100644 ---- a/components/engine/vendor/github.com/containerd/containerd/process.go -+++ b/components/engine/vendor/github.com/containerd/containerd/process.go -@@ -26,6 +26,7 @@ import ( - "github.com/containerd/containerd/cio" - "github.com/containerd/containerd/errdefs" - "github.com/pkg/errors" -+ "github.com/sirupsen/logrus" - ) - - // Process represents a system process -@@ -111,9 +112,19 @@ func (p *process) Start(ctx context.Context) error { - ExecID: p.id, - }) - if err != nil { -- p.io.Cancel() -- p.io.Wait() -- p.io.Close() -+ done := make(chan struct{}) -+ go func() { -+ p.io.Cancel() -+ p.io.Wait() -+ p.io.Close() -+ close(done) -+ }() -+ select { -+ case <-time.After(30 * time.Second): -+ logrus.Warnf("process start failed with error %v, wait io close timeout, some fifo io may be dropped.", err) -+ case <-done: -+ // ok -+ } - return errdefs.FromGRPC(err) - } - p.pid = r.Pid --- -1.8.3.1 - diff --git a/patch/0185-docker-delete-image-reference-when-failed-to-get-ima.patch b/patch/0185-docker-delete-image-reference-when-failed-to-get-ima.patch deleted file mode 100644 index bf84f7b..0000000 --- a/patch/0185-docker-delete-image-reference-when-failed-to-get-ima.patch +++ /dev/null @@ -1,63 +0,0 @@ -From cfc92becb2605d67a7391c43261e698d0fdd57bd Mon Sep 17 00:00:00 2001 -From: xiadanni -Date: Fri, 15 Jan 2021 15:37:42 +0800 -Subject: [PATCH] docker: delete image reference when failed to get image - configuration to avoid docker pull error - -according to patch 0110-docker-Fix-can-t-pull-image-while-the-image-i.patch, -if the layers of image has been damaged, image reference should be -deleted from repositories.json to avoid docker pull failed. - -however, when imageStore.Get failed, isExist flag has not been set to -false, which cause the image reference has still not been deleted, only -warning is printed. - -flood warnings printed every time user restarts docker daemon, like: -Jan 15 14:09:52 localhost dockerd[3952467]: -time="2021-01-15T14:09:52.705664179+08:00" level=warning msg="Failed to -get image configration for image id -sha256:d0a015ffac5ba3b9d2a641de56b3b2ed24409b7082c7811ebac4c2f4977b0965, -error: failed to get digest -sha256:d0a015ffac5ba3b9d2a641de56b3b2ed24409b7082c7811ebac4c2f4977b0965: -open -/var/lib/docker/image/devicemapper/imagedb/content/sha256/d0a015ffac5ba3b9d2a641de56b3b2ed24409b7082c7811ebac4c2f4977b0965: -no such file or directory" - -so we fix the logic, delete image reference when failed to get image -configuration. - -Signed-off-by: xiadanni ---- - components/engine/daemon/daemon.go | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index e826f6a..ed268d2 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -1097,11 +1097,10 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S - return nil, err - } - -- // delete reference of image not nornamlly loaded to imageStore -- var isExist bool -+ // delete reference of image not normally loaded to imageStore - for _, imageID := range rs.List() { -+ isExist := false - if img, err := imageStore.Get(image.ID(imageID)); err == nil { -- isExist = false - if chainID := img.RootFS.ChainID(); chainID != "" { - l, err := layerStores[runtime.GOOS].Get(chainID) - if err == nil { -@@ -1112,7 +1111,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S - isExist = true - } - } else { -- logrus.Warnf("Failed to get image configration for image id %s, error: %s", imageID, err) -+ logrus.Warnf("Failed to get image configuration for image id %s, error: %s", imageID, err) - } - - // If the image not exist locally, delete its reference --- -1.8.3.1 - diff --git a/patch/0186-docker-fix-execCommands-leak-in-health-check.patch b/patch/0186-docker-fix-execCommands-leak-in-health-check.patch deleted file mode 100644 index 48ab5c0..0000000 --- a/patch/0186-docker-fix-execCommands-leak-in-health-check.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 83ef8cfec0df0388bb92788d9c3ec2a306ab7f20 Mon Sep 17 00:00:00 2001 -From: jingrui -Date: Wed, 20 Jan 2021 17:07:12 +0800 -Subject: [PATCH] docker: fix execCommands leak in health-check - -Change-Id: I6bd02bc4a8e08b8de58bc454be8944c73175b3ae -Signed-off-by: jingrui ---- - components/engine/daemon/daemon.go | 5 +---- - components/engine/daemon/exec/exec.go | 7 +++++++ - components/engine/daemon/health.go | 2 +- - 3 files changed, 9 insertions(+), 5 deletions(-) - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index ed268d2c4f..57ad832eb2 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -404,10 +404,6 @@ func (daemon *Daemon) restore() error { - if c.IsRunning() || c.IsPaused() { - c.RestartManager().Cancel() // manually start containers because some need to wait for swarm networking - -- c.Lock() -- daemon.initHealthMonitor(c) -- c.Unlock() -- - if c.IsPaused() && alive { - s, err := daemon.containerd.Status(context.Background(), c.ID) - if err != nil { -@@ -450,6 +446,7 @@ func (daemon *Daemon) restore() error { - - if getProbe(c) != nil { - c.Lock() -+ daemon.initHealthMonitor(c) - if err := c.CheckpointTo(daemon.containersReplica); err != nil { - logrus.WithError(err).WithField("container", c.ID). - Error("Failed to checkpoint container state") -diff --git a/components/engine/daemon/exec/exec.go b/components/engine/daemon/exec/exec.go -index 08fc87c4b0..47644fc158 100644 ---- a/components/engine/daemon/exec/exec.go -+++ b/components/engine/daemon/exec/exec.go -@@ -145,3 +145,10 @@ func (e *Store) List() []string { - e.RUnlock() - return IDs - } -+ -+func (e *Store) Size() int { -+ e.RLock() -+ num := len(e.byID) -+ e.RUnlock() -+ return num -+} -diff --git a/components/engine/daemon/health.go b/components/engine/daemon/health.go -index 5f26ee5db8..c181850309 100644 ---- a/components/engine/daemon/health.go -+++ b/components/engine/daemon/health.go -@@ -202,7 +202,7 @@ func monitor(d *Daemon, c *container.Container, stop chan struct{}, probe probe) - result, err := probe.run(ctx, d, c) - if err != nil { - healthChecksFailedCounter.Inc() -- logrus.Warnf("Health check for container %s error: %v", c.ID, err) -+ logrus.Warnf("exec-cmds=%d Health check for container %s error: %v", c.ExecCommands.Size(), c.ID, err) - results <- &types.HealthcheckResult{ - ExitCode: -1, - Output: err.Error(), --- -2.17.1 - diff --git a/patch/0188-docker-check-containerd-pid-before-kill-it.patch b/patch/0188-docker-check-containerd-pid-before-kill-it.patch deleted file mode 100644 index 8e62357..0000000 --- a/patch/0188-docker-check-containerd-pid-before-kill-it.patch +++ /dev/null @@ -1,121 +0,0 @@ -From eda3fe6001fcf911e4630818514df6ad6531417d Mon Sep 17 00:00:00 2001 -From: xiadanni -Date: Thu, 28 Jan 2021 16:02:47 +0800 -Subject: [PATCH] docker: check containerd pid before kill it - -Signed-off-by: xiadanni ---- - .../libcontainerd/supervisor/remote_daemon.go | 6 ++++++ - .../libcontainerd/supervisor/remote_daemon_linux.go | 15 +++++++++++---- - components/engine/utils/utils.go | 21 +++++++++++++++++++++ - 3 files changed, 38 insertions(+), 4 deletions(-) - -diff --git a/components/engine/libcontainerd/supervisor/remote_daemon.go b/components/engine/libcontainerd/supervisor/remote_daemon.go -index 19582cd..5cb6de0 100644 ---- a/components/engine/libcontainerd/supervisor/remote_daemon.go -+++ b/components/engine/libcontainerd/supervisor/remote_daemon.go -@@ -18,6 +18,7 @@ import ( - "github.com/containerd/containerd" - "github.com/containerd/containerd/services/server" - "github.com/docker/docker/pkg/system" -+ "github.com/docker/docker/utils" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" -@@ -139,6 +140,11 @@ func (r *remote) getContainerdPid() (int, error) { - if err != nil { - return -1, err - } -+ -+ if !utils.IsContainerdPid(int(pid)) { -+ return -1, nil -+ } -+ - if system.IsProcessAlive(int(pid)) { - return int(pid), nil - } -diff --git a/components/engine/libcontainerd/supervisor/remote_daemon_linux.go b/components/engine/libcontainerd/supervisor/remote_daemon_linux.go -index 799399c..3ccd38b 100644 ---- a/components/engine/libcontainerd/supervisor/remote_daemon_linux.go -+++ b/components/engine/libcontainerd/supervisor/remote_daemon_linux.go -@@ -8,6 +8,7 @@ import ( - - "github.com/containerd/containerd/defaults" - "github.com/docker/docker/pkg/system" -+ "github.com/docker/docker/utils" - ) - - const ( -@@ -42,7 +43,7 @@ func (r *remote) setDefaults() { - - func (r *remote) stopDaemon() { - // Ask the daemon to quit -- syscall.Kill(r.daemonPid, syscall.SIGTERM) -+ DoKillContainerd(r.daemonPid, syscall.SIGTERM) - // Wait up to 15secs for it to stop - for i := time.Duration(0); i < shutdownTimeout; i += time.Second { - if !system.IsProcessAlive(r.daemonPid) { -@@ -53,15 +54,21 @@ func (r *remote) stopDaemon() { - - if system.IsProcessAlive(r.daemonPid) { - r.logger.WithField("pid", r.daemonPid).Warn("daemon didn't stop within 15 secs, killing it") -- syscall.Kill(r.daemonPid, syscall.SIGKILL) -+ DoKillContainerd(r.daemonPid, syscall.SIGKILL) -+ } -+} -+ -+func DoKillContainerd(pid int, sig syscall.Signal) { -+ if utils.IsContainerdPid(pid) { -+ syscall.Kill(pid, sig) - } - } - - func (r *remote) killDaemon() { - // Try to get a stack trace -- syscall.Kill(r.daemonPid, syscall.SIGUSR1) -+ DoKillContainerd(r.daemonPid, syscall.SIGUSR1) - <-time.After(100 * time.Millisecond) -- system.KillProcess(r.daemonPid) -+ DoKillContainerd(r.daemonPid, syscall.SIGKILL) - } - - func (r *remote) platformCleanup() { -diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go -index 53893fc..c394456 100644 ---- a/components/engine/utils/utils.go -+++ b/components/engine/utils/utils.go -@@ -19,6 +19,12 @@ int mysemctl(int cmd, struct seminfo *p){ - import "C" - import ( - "fmt" -+ "io/ioutil" -+ "path/filepath" -+ "strconv" -+ "strings" -+ -+ "github.com/sirupsen/logrus" - ) - - func CheckSemSetStat() (int, int, error) { -@@ -30,3 +36,18 @@ func CheckSemSetStat() (int, int, error) { - } - return int(seminfo.semusz), int(seminfo.semmni), err - } -+ -+func IsContainerdPid(pid int) bool { -+ if pid <= 1 { -+ logrus.Warnf("pid %d is not containerd", pid) -+ return false -+ } -+ -+ cmdlineBytes, err := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "cmdline")) -+ if err == nil && !strings.Contains(string(cmdlineBytes), "containerd") { -+ logrus.Warnf("pid %d is not containerd, cmdline: %s", pid, string(cmdlineBytes)) -+ return false -+ } -+ -+ return true -+} --- -1.8.3.1 - diff --git a/patch/0189-docker-fix-Access-to-remapped-root-allows-privilege-.patch b/patch/0189-docker-fix-Access-to-remapped-root-allows-privilege-.patch deleted file mode 100644 index bd64cdb..0000000 --- a/patch/0189-docker-fix-Access-to-remapped-root-allows-privilege-.patch +++ /dev/null @@ -1,446 +0,0 @@ -From 870a0fb061a51d96b3e4f56c12a3819c3865182c Mon Sep 17 00:00:00 2001 -From: xiadanni -Date: Wed, 24 Feb 2021 16:27:51 +0800 -Subject: [PATCH] Fix Access to remapped root allows privilege escalation to - real root(CVE-2021-21284) - -Signed-off-by: xiadanni ---- - components/engine/daemon/container_operations_unix.go | 2 +- - components/engine/daemon/create.go | 5 ++--- - components/engine/daemon/daemon.go | 10 ++++------ - components/engine/daemon/daemon_unix.go | 14 ++++++++++---- - components/engine/daemon/graphdriver/aufs/aufs.go | 9 +++------ - components/engine/daemon/graphdriver/btrfs/btrfs.go | 10 +++------- - components/engine/daemon/graphdriver/overlay/overlay.go | 16 +++++++--------- - components/engine/daemon/graphdriver/overlay2/overlay.go | 12 ++++-------- - components/engine/daemon/graphdriver/vfs/driver.go | 5 ++--- - components/engine/daemon/graphdriver/zfs/zfs.go | 6 +----- - components/engine/pkg/idtools/idtools.go | 11 ++++++++--- - components/engine/pkg/idtools/idtools_unix.go | 14 ++++++++++---- - components/engine/volume/local/local.go | 11 +++++++++-- - 13 files changed, 64 insertions(+), 61 deletions(-) - -diff --git a/components/engine/daemon/container_operations_unix.go b/components/engine/daemon/container_operations_unix.go -index df2f326..ff2d772 100644 ---- a/components/engine/daemon/container_operations_unix.go -+++ b/components/engine/daemon/container_operations_unix.go -@@ -425,5 +425,5 @@ func (daemon *Daemon) setupContainerMountsRoot(c *container.Container) error { - if err != nil { - return err - } -- return idtools.MkdirAllAndChown(p, 0700, daemon.idMapping.RootPair()) -+ return idtools.MkdirAllAndChown(p, 0701, idtools.CurrentIdentity()) - } -diff --git a/components/engine/daemon/create.go b/components/engine/daemon/create.go -index 7733d7b..4d083e7 100644 ---- a/components/engine/daemon/create.go -+++ b/components/engine/daemon/create.go -@@ -190,11 +190,10 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig, managed bool) ( - return nil, err - } - -- rootIDs := daemon.idMapping.RootPair() -- if err := idtools.MkdirAndChown(container.Root, 0700, rootIDs); err != nil { -+ if err := idtools.MkdirAndChown(container.Root, 0701, idtools.CurrentIdentity()); err != nil { - return nil, err - } -- if err := idtools.MkdirAndChown(container.CheckpointDir(), 0700, rootIDs); err != nil { -+ if err := idtools.MkdirAndChown(container.CheckpointDir(), 0700, idtools.CurrentIdentity()); err != nil { - return nil, err - } - -diff --git a/components/engine/daemon/daemon.go b/components/engine/daemon/daemon.go -index 57ad832..b3039ab 100644 ---- a/components/engine/daemon/daemon.go -+++ b/components/engine/daemon/daemon.go -@@ -849,7 +849,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S - } - - // set up the tmpDir to use a canonical path -- tmp, err := prepareTempDir(config.Root, rootIDs) -+ tmp, err := prepareTempDir(config.Root) - if err != nil { - return nil, fmt.Errorf("Unable to get the TempDir under %s: %s", config.Root, err) - } -@@ -913,7 +913,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S - } - - daemonRepo := filepath.Join(config.Root, "containers") -- if err := idtools.MkdirAllAndChown(daemonRepo, 0700, rootIDs); err != nil { -+ if err := idtools.MkdirAllAndChown(daemonRepo, 0701, idtools.CurrentIdentity()); err != nil { - return nil, err - } - -@@ -1422,7 +1422,7 @@ func (daemon *Daemon) Subnets() ([]net.IPNet, []net.IPNet) { - // prepareTempDir prepares and returns the default directory to use - // for temporary files. - // If it doesn't exist, it is created. If it exists, its content is removed. --func prepareTempDir(rootDir string, rootIdentity idtools.Identity) (string, error) { -+func prepareTempDir(rootDir string) (string, error) { - var tmpDir string - if tmpDir = os.Getenv("DOCKER_TMPDIR"); tmpDir == "" { - tmpDir = filepath.Join(rootDir, "tmp") -@@ -1440,9 +1440,7 @@ func prepareTempDir(rootDir string, rootIdentity idtools.Identity) (string, erro - } - } - } -- // We don't remove the content of tmpdir if it's not the default, -- // it may hold things that do not belong to us. -- return tmpDir, idtools.MkdirAllAndChown(tmpDir, 0700, rootIdentity) -+ return tmpDir, idtools.MkdirAllAndChown(tmpDir, 0700, idtools.CurrentIdentity()) - } - - func (daemon *Daemon) setGenericResources(conf *config.Config) error { -diff --git a/components/engine/daemon/daemon_unix.go b/components/engine/daemon/daemon_unix.go -index af50fa3..07a0aa0 100644 ---- a/components/engine/daemon/daemon_unix.go -+++ b/components/engine/daemon/daemon_unix.go -@@ -1271,7 +1271,7 @@ func setupRemappedRoot(config *config.Config) (*idtools.IdentityMapping, error) - return &idtools.IdentityMapping{}, nil - } - --func setupDaemonRoot(config *config.Config, rootDir string, rootIdentity idtools.Identity) error { -+func setupDaemonRoot(config *config.Config, rootDir string, remappedRoot idtools.Identity) error { - config.Root = rootDir - // the docker root metadata directory needs to have execute permissions for all users (g+x,o+x) - // so that syscalls executing as non-root, operating on subdirectories of the graph root -@@ -1296,10 +1296,16 @@ func setupDaemonRoot(config *config.Config, rootDir string, rootIdentity idtools - // a new subdirectory with ownership set to the remapped uid/gid (so as to allow - // `chdir()` to work for containers namespaced to that uid/gid) - if config.RemappedRoot != "" { -- config.Root = filepath.Join(rootDir, fmt.Sprintf("%d.%d", rootIdentity.UID, rootIdentity.GID)) -+ id := idtools.CurrentIdentity() -+ // First make sure the current root dir has the correct perms. -+ if err := idtools.MkdirAllAndChown(config.Root, 0701, id); err != nil { -+ return errors.Wrapf(err, "could not create or set daemon root permissions: %s", config.Root) -+ } -+ -+ config.Root = filepath.Join(rootDir, fmt.Sprintf("%d.%d", remappedRoot.UID, remappedRoot.GID)) - logrus.Debugf("Creating user namespaced daemon root: %s", config.Root) - // Create the root directory if it doesn't exist -- if err := idtools.MkdirAllAndChown(config.Root, 0700, rootIdentity); err != nil { -+ if err := idtools.MkdirAllAndChown(config.Root, 0701, id); err != nil { - return fmt.Errorf("Cannot create daemon root: %s: %v", config.Root, err) - } - // we also need to verify that any pre-existing directories in the path to -@@ -1312,7 +1318,7 @@ func setupDaemonRoot(config *config.Config, rootDir string, rootIdentity idtools - if dirPath == "/" { - break - } -- if !idtools.CanAccess(dirPath, rootIdentity) { -+ if !idtools.CanAccess(dirPath, remappedRoot) { - return fmt.Errorf("a subdirectory in your graphroot path (%s) restricts access to the remapped root uid/gid; please fix by allowing 'o+x' permissions on existing directories", config.Root) - } - } -diff --git a/components/engine/daemon/graphdriver/aufs/aufs.go b/components/engine/daemon/graphdriver/aufs/aufs.go -index eef8387..4ee3682 100644 ---- a/components/engine/daemon/graphdriver/aufs/aufs.go -+++ b/components/engine/daemon/graphdriver/aufs/aufs.go -@@ -130,18 +130,15 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap - locker: locker.New(), - } - -- rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) -- if err != nil { -- return nil, err -- } -+ currentID := idtools.CurrentIdentity() - // Create the root aufs driver dir -- if err := idtools.MkdirAllAndChown(root, 0700, idtools.Identity{UID: rootUID, GID: rootGID}); err != nil { -+ if err := idtools.MkdirAllAndChown(root, 0701, currentID); err != nil { - return nil, err - } - - // Populate the dir structure - for _, p := range paths { -- if err := idtools.MkdirAllAndChown(path.Join(root, p), 0700, idtools.Identity{UID: rootUID, GID: rootGID}); err != nil { -+ if err := idtools.MkdirAllAndChown(path.Join(root, p), 0701, currentID); err != nil { - return nil, err - } - } -diff --git a/components/engine/daemon/graphdriver/btrfs/btrfs.go b/components/engine/daemon/graphdriver/btrfs/btrfs.go -index 7d1f9dc..d76e144 100644 ---- a/components/engine/daemon/graphdriver/btrfs/btrfs.go -+++ b/components/engine/daemon/graphdriver/btrfs/btrfs.go -@@ -70,11 +70,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap - return nil, graphdriver.ErrPrerequisites - } - -- rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) -- if err != nil { -- return nil, err -- } -- if err := idtools.MkdirAllAndChown(home, 0700, idtools.Identity{UID: rootUID, GID: rootGID}); err != nil { -+ if err := idtools.MkdirAllAndChown(home, 0701, idtools.CurrentIdentity()); err != nil { - return nil, err - } - -@@ -535,7 +531,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error { - if err != nil { - return err - } -- if err := idtools.MkdirAllAndChown(subvolumes, 0700, idtools.Identity{UID: rootUID, GID: rootGID}); err != nil { -+ if err := idtools.MkdirAllAndChown(subvolumes, 0701, idtools.CurrentIdentity()); err != nil { - return err - } - if parent == "" { -@@ -570,7 +566,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error { - if err := d.setStorageSize(path.Join(subvolumes, id), driver); err != nil { - return err - } -- if err := idtools.MkdirAllAndChown(quotas, 0700, idtools.Identity{UID: rootUID, GID: rootGID}); err != nil { -+ if err := idtools.MkdirAllAndChown(quotas, 0700, idtools.CurrentIdentity()); err != nil { - return err - } - if err := ioutil.WriteFile(path.Join(quotas, id), []byte(fmt.Sprint(driver.options.size)), 0644); err != nil { -diff --git a/components/engine/daemon/graphdriver/overlay/overlay.go b/components/engine/daemon/graphdriver/overlay/overlay.go -index 7dbeec5..a9e65a3 100644 ---- a/components/engine/daemon/graphdriver/overlay/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay/overlay.go -@@ -163,12 +163,8 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap - logrus.WithField("storage-driver", "overlay").Warn(overlayutils.ErrDTypeNotSupported("overlay", backingFs)) - } - -- rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) -- if err != nil { -- return nil, err -- } - // Create the driver home dir -- if err := idtools.MkdirAllAndChown(home, 0700, idtools.Identity{UID: rootUID, GID: rootGID}); err != nil { -+ if err := idtools.MkdirAllAndChown(home, 0701, idtools.CurrentIdentity()); err != nil { - return nil, err - } - -@@ -303,10 +299,11 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr - } - root := idtools.Identity{UID: rootUID, GID: rootGID} - -- if err := idtools.MkdirAllAndChown(path.Dir(dir), 0700, root); err != nil { -+ currentID := idtools.CurrentIdentity() -+ if err := idtools.MkdirAllAndChown(path.Dir(dir), 0701, currentID); err != nil { - return err - } -- if err := idtools.MkdirAndChown(dir, 0700, root); err != nil { -+ if err := idtools.MkdirAndChown(dir, 0701, currentID); err != nil { - return err - } - -@@ -319,6 +316,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr - - // Toplevel images are just a "root" dir - if parent == "" { -+ // This must be 0755 otherwise unprivileged users will in the container will not be able to read / in the container - return idtools.MkdirAndChown(path.Join(dir, "root"), 0755, root) - } - -@@ -339,7 +337,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr - if err := idtools.MkdirAndChown(path.Join(dir, "work"), 0700, root); err != nil { - return err - } -- return ioutil.WriteFile(path.Join(dir, "lower-id"), []byte(parent), 0666) -+ return ioutil.WriteFile(path.Join(dir, "lower-id"), []byte(parent), 0600) - } - - // Otherwise, copy the upper and the lower-id from the parent -@@ -349,7 +347,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr - return err - } - -- if err := ioutil.WriteFile(path.Join(dir, "lower-id"), lowerID, 0666); err != nil { -+ if err := ioutil.WriteFile(path.Join(dir, "lower-id"), lowerID, 0600); err != nil { - return err - } - -diff --git a/components/engine/daemon/graphdriver/overlay2/overlay.go b/components/engine/daemon/graphdriver/overlay2/overlay.go -index 7fac2c3..7576320 100644 ---- a/components/engine/daemon/graphdriver/overlay2/overlay.go -+++ b/components/engine/daemon/graphdriver/overlay2/overlay.go -@@ -197,12 +197,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap - logger.Warn(overlayutils.ErrDTypeNotSupported("overlay2", backingFs)) - } - -- rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) -- if err != nil { -- return nil, err -- } -- // Create the driver home dir -- if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 0700, idtools.Identity{UID: rootUID, GID: rootGID}); err != nil { -+ if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 0701, idtools.CurrentIdentity()); err != nil { - return nil, err - } - -@@ -429,11 +424,12 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr - return err - } - root := idtools.Identity{UID: rootUID, GID: rootGID} -+ current := idtools.CurrentIdentity() - -- if err := idtools.MkdirAllAndChown(path.Dir(dir), 0700, root); err != nil { -+ if err := idtools.MkdirAllAndChown(path.Dir(dir), 0701, current); err != nil { - return err - } -- if err := idtools.MkdirAndChown(dir, 0700, root); err != nil { -+ if err := idtools.MkdirAndChown(dir, 0701, current); err != nil { - return err - } - -diff --git a/components/engine/daemon/graphdriver/vfs/driver.go b/components/engine/daemon/graphdriver/vfs/driver.go -index 6b9e92e..15ac251 100644 ---- a/components/engine/daemon/graphdriver/vfs/driver.go -+++ b/components/engine/daemon/graphdriver/vfs/driver.go -@@ -30,8 +30,7 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap - home: home, - idMapping: idtools.NewIDMappingsFromMaps(uidMaps, gidMaps), - } -- rootIDs := d.idMapping.RootPair() -- if err := idtools.MkdirAllAndChown(home, 0700, rootIDs); err != nil { -+ if err := idtools.MkdirAllAndChown(home, 0701, idtools.CurrentIdentity()); err != nil { - return nil, err - } - -@@ -116,7 +115,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error { - func (d *Driver) create(id, parent string, size uint64) error { - dir := d.dir(id) - rootIDs := d.idMapping.RootPair() -- if err := idtools.MkdirAllAndChown(filepath.Dir(dir), 0700, rootIDs); err != nil { -+ if err := idtools.MkdirAllAndChown(filepath.Dir(dir), 0701, idtools.CurrentIdentity()); err != nil { - return err - } - if err := idtools.MkdirAndChown(dir, 0755, rootIDs); err != nil { -diff --git a/components/engine/daemon/graphdriver/zfs/zfs.go b/components/engine/daemon/graphdriver/zfs/zfs.go -index e595809..4484c51 100644 ---- a/components/engine/daemon/graphdriver/zfs/zfs.go -+++ b/components/engine/daemon/graphdriver/zfs/zfs.go -@@ -102,11 +102,7 @@ func Init(base string, opt []string, uidMaps, gidMaps []idtools.IDMap) (graphdri - return nil, fmt.Errorf("BUG: zfs get all -t filesystem -rHp '%s' should contain '%s'", options.fsName, options.fsName) - } - -- rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) -- if err != nil { -- return nil, fmt.Errorf("Failed to get root uid/guid: %v", err) -- } -- if err := idtools.MkdirAllAndChown(base, 0700, idtools.Identity{UID: rootUID, GID: rootGID}); err != nil { -+ if err := idtools.MkdirAllAndChown(base, 0701, idtools.CurrentIdentity()); err != nil { - return nil, fmt.Errorf("Failed to create '%s': %v", base, err) - } - -diff --git a/components/engine/pkg/idtools/idtools.go b/components/engine/pkg/idtools/idtools.go -index 230422e..3e2ce75 100644 ---- a/components/engine/pkg/idtools/idtools.go -+++ b/components/engine/pkg/idtools/idtools.go -@@ -36,13 +36,13 @@ const ( - - // MkdirAllAndChown creates a directory (include any along the path) and then modifies - // ownership to the requested uid/gid. If the directory already exists, this --// function will still change ownership to the requested uid/gid pair. -+// function will still change ownership and permissions. - func MkdirAllAndChown(path string, mode os.FileMode, owner Identity) error { - return mkdirAs(path, mode, owner, true, true) - } - - // MkdirAndChown creates a directory and then modifies ownership to the requested uid/gid. --// If the directory already exists, this function still changes ownership. -+// If the directory already exists, this function still changes ownership and permissions. - // Note that unlike os.Mkdir(), this function does not return IsExist error - // in case path already exists. - func MkdirAndChown(path string, mode os.FileMode, owner Identity) error { -@@ -51,7 +51,7 @@ func MkdirAndChown(path string, mode os.FileMode, owner Identity) error { - - // MkdirAllAndChownNew creates a directory (include any along the path) and then modifies - // ownership ONLY of newly created directories to the requested uid/gid. If the --// directories along the path exist, no change of ownership will be performed -+// directories along the path exist, no change of ownership or permissions will be performed - func MkdirAllAndChownNew(path string, mode os.FileMode, owner Identity) error { - return mkdirAs(path, mode, owner, true, false) - } -@@ -265,3 +265,8 @@ func parseSubidFile(path, username string) (ranges, error) { - } - return rangeList, nil - } -+ -+// CurrentIdentity returns the identity of the current process -+func CurrentIdentity() Identity { -+ return Identity{UID: os.Getuid(), GID: os.Getegid()} -+} -diff --git a/components/engine/pkg/idtools/idtools_unix.go b/components/engine/pkg/idtools/idtools_unix.go -index fb23974..329d5d0 100644 ---- a/components/engine/pkg/idtools/idtools_unix.go -+++ b/components/engine/pkg/idtools/idtools_unix.go -@@ -39,7 +39,7 @@ func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting - } - - // short-circuit--we were called with an existing directory and chown was requested -- return lazyChown(path, owner.UID, owner.GID, stat) -+ return setPermissions(path, mode, owner.UID, owner.GID, stat) - } - - if os.IsNotExist(err) { -@@ -70,7 +70,7 @@ func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting - // even if it existed, we will chown the requested path + any subpaths that - // didn't exist when we called MkdirAll - for _, pathComponent := range paths { -- if err := lazyChown(pathComponent, owner.UID, owner.GID, nil); err != nil { -+ if err := setPermissions(pathComponent, mode, owner.UID, owner.GID, nil); err != nil { - return err - } - } -@@ -213,10 +213,11 @@ func callGetent(args string) (io.Reader, error) { - return bytes.NewReader(out), nil - } - --// lazyChown performs a chown only if the uid/gid don't match what's requested -+// setPermissions performs a chown/chmod only if the uid/gid don't match what's requested - // Normally a Chown is a no-op if uid/gid match, but in some cases this can still cause an error, e.g. if the - // dir is on an NFS share, so don't call chown unless we absolutely must. --func lazyChown(p string, uid, gid int, stat *system.StatT) error { -+// Likewise for setting permissions. -+func setPermissions(p string, mode os.FileMode, uid, gid int, stat *system.StatT) error { - if stat == nil { - var err error - stat, err = system.Stat(p) -@@ -224,6 +225,11 @@ func lazyChown(p string, uid, gid int, stat *system.StatT) error { - return err - } - } -+ if os.FileMode(stat.Mode()).Perm() != mode.Perm() { -+ if err := os.Chmod(p, mode.Perm()); err != nil { -+ return err -+ } -+ } - if stat.UID() == uint32(uid) && stat.GID() == uint32(gid) { - return nil - } -diff --git a/components/engine/volume/local/local.go b/components/engine/volume/local/local.go -index ffdc61a..585f910 100644 ---- a/components/engine/volume/local/local.go -+++ b/components/engine/volume/local/local.go -@@ -49,7 +49,7 @@ type activeMount struct { - func New(scope string, rootIdentity idtools.Identity) (*Root, error) { - rootDirectory := filepath.Join(scope, volumesPathName) - -- if err := idtools.MkdirAllAndChown(rootDirectory, 0700, rootIdentity); err != nil { -+ if err := idtools.MkdirAllAndChown(rootDirectory, 0701, idtools.CurrentIdentity()); err != nil { - return nil, err - } - -@@ -153,8 +153,15 @@ func (r *Root) Create(name string, opts map[string]string) (volume.Volume, error - } - - path := r.DataPath(name) -+ volRoot := filepath.Dir(path) -+ // Root dir does not need to be accessed by the remapped root -+ if err := idtools.MkdirAllAndChown(volRoot, 0701, idtools.CurrentIdentity()); err != nil { -+ return nil, errors.Wrapf(errdefs.System(err), "error while creating volume root path '%s'", volRoot) -+ } -+ -+ // Remapped root does need access to the data path - if err := idtools.MkdirAllAndChown(path, 0755, r.rootIdentity); err != nil { -- return nil, errors.Wrapf(errdefs.System(err), "error while creating volume path '%s'", path) -+ return nil, errors.Wrapf(errdefs.System(err), "error while creating volume data path '%s'", path) - } - - var err error --- -1.8.3.1 - diff --git a/patch/0190-docker-fix-CVE-2021-21285.patch b/patch/0190-docker-fix-CVE-2021-21285.patch deleted file mode 100644 index c50004b..0000000 --- a/patch/0190-docker-fix-CVE-2021-21285.patch +++ /dev/null @@ -1,54 +0,0 @@ -From c6870e57fa9f7667c59dd21abd6e8034509b6ada Mon Sep 17 00:00:00 2001 -From: xiadanni -Date: Thu, 18 Mar 2021 14:41:15 +0800 -Subject: [PATCH] docker: prevent an invalid image from crashing docker daemon - (CVE-2021-21285) - -Change-Id: I0cf6a1b268e500a2a004c9d9d33f01a3d4ad5b47 -Signed-off-by: xiadanni ---- - .../engine/builder/builder-next/adapters/containerimage/pull.go | 3 +++ - components/engine/distribution/pull_v2.go | 6 ++++++ - 2 files changed, 9 insertions(+) - -diff --git a/components/engine/builder/builder-next/adapters/containerimage/pull.go b/components/engine/builder/builder-next/adapters/containerimage/pull.go -index f6e55f4..4b6eb04 100644 ---- a/components/engine/builder/builder-next/adapters/containerimage/pull.go -+++ b/components/engine/builder/builder-next/adapters/containerimage/pull.go -@@ -493,6 +493,9 @@ func (p *puller) Snapshot(ctx context.Context) (cache.ImmutableRef, error) { - layers := make([]xfer.DownloadDescriptor, 0, len(mfst.Layers)) - - for i, desc := range mfst.Layers { -+ if err := desc.Digest.Validate(); err != nil { -+ return nil, errors.Wrap(err, "layer digest could not be validated") -+ } - ongoing.add(desc) - layers = append(layers, &layerDescriptor{ - desc: desc, -diff --git a/components/engine/distribution/pull_v2.go b/components/engine/distribution/pull_v2.go -index 4150241..98714fd 100644 ---- a/components/engine/distribution/pull_v2.go -+++ b/components/engine/distribution/pull_v2.go -@@ -480,6 +480,9 @@ func (p *v2Puller) pullSchema1(ctx context.Context, ref reference.Reference, unv - // to top-most, so that the downloads slice gets ordered correctly. - for i := len(verifiedManifest.FSLayers) - 1; i >= 0; i-- { - blobSum := verifiedManifest.FSLayers[i].BlobSum -+ if err = blobSum.Validate(); err != nil { -+ return "", "", errors.Wrapf(err, "could not validate layer digest %q", blobSum) -+ } - - var throwAway struct { - ThrowAway bool `json:"throwaway,omitempty"` -@@ -596,6 +599,9 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s - // Note that the order of this loop is in the direction of bottom-most - // to top-most, so that the downloads slice gets ordered correctly. - for _, d := range mfst.Layers { -+ if err := d.Digest.Validate(); err != nil { -+ return "", "", errors.Wrapf(err, "could not validate layer digest %q", d.Digest) -+ } - layerDescriptor := &v2LayerDescriptor{ - digest: d.Digest, - repo: p.repo, --- -1.8.3.1 - diff --git a/patch/0191-rollback-if-docker-restart-when-doing-BlkDiscard.patch b/patch/0191-rollback-if-docker-restart-when-doing-BlkDiscard.patch deleted file mode 100644 index 1953bf7..0000000 --- a/patch/0191-rollback-if-docker-restart-when-doing-BlkDiscard.patch +++ /dev/null @@ -1,55 +0,0 @@ -From b7634618332c2d0ca7b59a4d63467c0038918ef0 Mon Sep 17 00:00:00 2001 -From: WangFengTu -Date: Thu, 1 Apr 2021 15:03:20 +0800 -Subject: [PATCH] rollback if docker restart when doing BlkDiscard - -Signed-off-by: WangFengTu ---- - .../daemon/graphdriver/devmapper/deviceset.go | 17 ++++++++--------- - 1 file changed, 8 insertions(+), 9 deletions(-) - -diff --git a/components/engine/daemon/graphdriver/devmapper/deviceset.go b/components/engine/daemon/graphdriver/devmapper/deviceset.go -index 750f2b13..9b6cb021 100644 ---- a/components/engine/daemon/graphdriver/devmapper/deviceset.go -+++ b/components/engine/daemon/graphdriver/devmapper/deviceset.go -@@ -2007,14 +2007,7 @@ func (devices *DeviceSet) markForDeferredDeletion(info *devInfo) error { - } - - // Should be called with devices.Lock() held. --func (devices *DeviceSet) deleteTransaction(info *devInfo, syncDelete bool) error { -- if err := devices.openTransaction(info.Hash, info.DeviceID); err != nil { -- logrus.WithField("storage-driver", "devicemapper").Debugf("Error opening transaction hash = %s deviceId = %d", "", info.DeviceID) -- return err -- } -- -- defer devices.closeTransaction() -- -+func (devices *DeviceSet) deleteDeviceNoLock(info *devInfo, syncDelete bool) error { - err := devicemapper.DeleteDevice(devices.getPoolDevName(), info.DeviceID) - if err != nil { - // If syncDelete is true, we want to return error. If deferred -@@ -2078,6 +2071,12 @@ func (devices *DeviceSet) issueDiscard(info *devInfo) error { - - // Should be called with devices.Lock() held. - func (devices *DeviceSet) deleteDevice(info *devInfo, syncDelete bool) error { -+ if err := devices.openTransaction(info.Hash, info.DeviceID); err != nil { -+ logrus.WithField("storage-driver", "devicemapper").Debugf("Error opening transaction hash = %s deviceId = %d", "", info.DeviceID) -+ return err -+ } -+ defer devices.closeTransaction() -+ - if devices.doBlkDiscard { - if err := devices.issueDiscard(info); err != nil { - return err -@@ -2099,7 +2098,7 @@ func (devices *DeviceSet) deleteDevice(info *devInfo, syncDelete bool) error { - return err - } - -- return devices.deleteTransaction(info, syncDelete) -+ return devices.deleteDeviceNoLock(info, syncDelete) - } - - // DeleteDevice will return success if device has been marked for deferred --- -2.25.1 - diff --git a/patch/0192-fix-dangling-unpigz.patch b/patch/0192-fix-dangling-unpigz.patch deleted file mode 100644 index 11d452b..0000000 --- a/patch/0192-fix-dangling-unpigz.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 6926d4e842dc26043cbdd38de5a8c0776f0d4d43 Mon Sep 17 00:00:00 2001 -From: WangFengTu -Date: Sun, 29 Aug 2021 15:49:03 +0800 -Subject: [PATCH] fix dangling unpigz - -Signed-off-by: WangFengTu ---- - components/engine/builder/dockerfile/copy.go | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/components/engine/builder/dockerfile/copy.go b/components/engine/builder/dockerfile/copy.go -index ad9b08df..c323e703 100644 ---- a/components/engine/builder/dockerfile/copy.go -+++ b/components/engine/builder/dockerfile/copy.go -@@ -527,6 +527,7 @@ func isArchivePath(driver containerfs.ContainerFS, path string) bool { - if err != nil { - return false - } -+ defer rdr.Close() - r := tar.NewReader(rdr) - _, err = r.Next() - return err == nil --- -2.25.1 - -- Gitee