요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0-only
.. Copyright (C) 2022 Meta Platforms, Inc. and affiliates.
=========================
BPF_MAP_TYPE_CGRP_STORAGE
=========================
The ``BPF_MAP_TYPE_CGRP_STORAGE`` map type represents a local fix-sized
storage for cgroups. It is only available with ``CONFIG_CGROUPS``.
The programs are made available by the same Kconfig. The
data for a particular cgroup can be retrieved by looking up the map
with that cgroup.
This document describes the usage and semantics of the
``BPF_MAP_TYPE_CGRP_STORAGE`` map type.
Usage
=====
The map key must be ``sizeof(int)`` representing a cgroup fd.
To access the storage in a program, use ``bpf_cgrp_storage_get``::
void *bpf_cgrp_storage_get(struct bpf_map *map, struct cgroup *cgroup, void *value, u64 flags)
``flags`` could be 0 or ``BPF_LOCAL_STORAGE_GET_F_CREATE`` which indicates that
a new local storage will be created if one does not exist.
The local storage can be removed with ``bpf_cgrp_storage_delete``::
long bpf_cgrp_storage_delete(struct bpf_map *map, struct cgroup *cgroup)
The map is available to all program types.
Examples
========
A BPF program example with BPF_MAP_TYPE_CGRP_STORAGE::
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
struct {
__uint(type, BPF_MAP_TYPE_CGRP_STORAGE);
__uint(map_flags, BPF_F_NO_PREALLOC);
__type(key, int);
__type(value, long);
} cgrp_storage SEC(".maps");
SEC("tp_btf/sys_enter")
int BPF_PROG(on_enter, struct pt_regs *regs, long id)
{
struct task_struct *task = bpf_get_current_task_btf();
long *ptr;
ptr = bpf_cgrp_storage_get(&cgrp_storage, task->cgroups->dfl_cgrp, 0,
BPF_LOCAL_STORAGE_GET_F_CREATE);
if (ptr)
__sync_fetch_and_add(ptr, 1);
return 0;
}
Userspace accessing map declared above::
#include <linux/bpf.h>
#include <linux/libbpf.h>
__u32 map_lookup(struct bpf_map *map, int cgrp_fd)
{
__u32 *value;
value = bpf_map_lookup_elem(bpf_map__fd(map), &cgrp_fd);
if (value)
return *value;
return 0;
}
Difference Between BPF_MAP_TYPE_CGRP_STORAGE and BPF_MAP_TYPE_CGROUP_STORAGE
============================================================================
The old cgroup storage map ``BPF_MAP_TYPE_CGROUP_STORAGE`` has been marked as
deprecated (renamed to ``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED``). The new
``BPF_MAP_TYPE_CGRP_STORAGE`` map should be used instead. The following
illusates the main difference between ``BPF_MAP_TYPE_CGRP_STORAGE`` and
``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED``.
(1). ``BPF_MAP_TYPE_CGRP_STORAGE`` can be used by all program types while
``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`` is available only to cgroup program types
like BPF_CGROUP_INET_INGRESS or BPF_CGROUP_SOCK_OPS, etc.
(2). ``BPF_MAP_TYPE_CGRP_STORAGE`` supports local storage for more than one
cgroup while ``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`` only supports one cgroup
which is attached by a BPF program.
(3). ``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`` allocates local storage at attach time so
``bpf_get_local_storage()`` always returns non-NULL local storage.
``BPF_MAP_TYPE_CGRP_STORAGE`` allocates local storage at runtime so
it is possible that ``bpf_cgrp_storage_get()`` may return null local storage.
To avoid such null local storage issue, user space can do
``bpf_map_update_elem()`` to pre-allocate local storage before a BPF program
is attached.
(4). ``BPF_MAP_TYPE_CGRP_STORAGE`` supports deleting local storage by a BPF program
while ``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`` only deletes storage during
prog detach time.
So overall, ``BPF_MAP_TYPE_CGRP_STORAGE`` supports all ``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED``
functionality and beyond. It is recommended to use ``BPF_MAP_TYPE_CGRP_STORAGE``
instead of ``BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED``.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Cgroup local storage 개요
1-16`BPF_MAP_TYPE_CGRP_STORAGE` 문서는 `GPL-2.0-only` 라이선스와 `Copyright (C) 2022 Meta Platforms, Inc. and affiliates.`를 명시합니다.
`BPF_MAP_TYPE_CGRP_STORAGE` map type은 cgroup을 위한 local fixed-size storage를 나타냅니다. 이 map은 `CONFIG_CGROUPS`를 설정한 경우에만 사용할 수 있으며, 관련 program도 같은 Kconfig 설정으로 제공됩니다.
특정 cgroup의 data는 해당 cgroup으로 map lookup을 수행해 가져올 수 있습니다. 이 문서는 `BPF_MAP_TYPE_CGRP_STORAGE` map type의 사용법과 semantics를 설명합니다.
Key와 storage helper 사용법
17-33Map key의 크기는 cgroup fd를 나타내는 `sizeof(int)`여야 합니다. Program에서 storage에 접근할 때는 다음 `bpf_cgrp_storage_get` helper를 사용합니다.
void *bpf_cgrp_storage_get(struct bpf_map *map, struct cgroup *cgroup, void *value, u64 flags)
`flags`에는 0 또는 `BPF_LOCAL_STORAGE_GET_F_CREATE`를 지정할 수 있습니다. 후자를 지정하면 local storage가 없을 때 새 storage를 생성합니다.
Local storage를 제거하려면 다음 `bpf_cgrp_storage_delete` helper를 사용합니다.
long bpf_cgrp_storage_delete(struct bpf_map *map, struct cgroup *cgroup)
`BPF_MAP_TYPE_CGRP_STORAGE` map은 모든 BPF program type에서 사용할 수 있습니다.
Kernel BPF와 userspace 접근 예제
34-77다음 BPF program은 key가 `int`, value가 `long`인 `BPF_MAP_TYPE_CGRP_STORAGE` map을 `BPF_F_NO_PREALLOC` flag와 함께 선언합니다. `tp_btf/sys_enter` program은 `bpf_get_current_task_btf()`로 현재 task를 얻고 `task->cgroups->dfl_cgrp`의 storage를 조회하거나 생성한 뒤, pointer가 유효하면 `__sync_fetch_and_add()`로 counter를 증가시킵니다.
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
struct {
__uint(type, BPF_MAP_TYPE_CGRP_STORAGE);
__uint(map_flags, BPF_F_NO_PREALLOC);
__type(key, int);
__type(value, long);
} cgrp_storage SEC(".maps");
SEC("tp_btf/sys_enter")
int BPF_PROG(on_enter, struct pt_regs *regs, long id)
{
struct task_struct *task = bpf_get_current_task_btf();
long *ptr;
ptr = bpf_cgrp_storage_get(&cgrp_storage, task->cgroups->dfl_cgrp, 0,
BPF_LOCAL_STORAGE_GET_F_CREATE);
if (ptr)
__sync_fetch_and_add(ptr, 1);
return 0;
}
다음 userspace 예제는 위에서 선언한 map의 fd를 `bpf_map__fd()`로 얻고 cgroup fd를 key로 `bpf_map_lookup_elem()`을 호출합니다. Lookup이 성공해 value pointer가 반환되면 해당 `__u32` 값을 반환하고, 그렇지 않으면 0을 반환합니다.
#include <linux/bpf.h>
#include <linux/libbpf.h>
__u32 map_lookup(struct bpf_map *map, int cgrp_fd)
{
__u32 *value;
value = bpf_map_lookup_elem(bpf_map__fd(map), &cgrp_fd);
if (value)
return *value;
return 0;
}
Deprecated cgroup storage와의 차이
78-109기존 cgroup storage map인 `BPF_MAP_TYPE_CGROUP_STORAGE`는 deprecated로 표시되었고 `BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`로 이름이 바뀌었습니다. 새 code에서는 `BPF_MAP_TYPE_CGRP_STORAGE`를 사용해야 합니다. 두 map type의 주요 차이는 다음과 같습니다.
- `BPF_MAP_TYPE_CGRP_STORAGE`는 모든 program type에서 사용할 수 있습니다. 반면 `BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`는 `BPF_CGROUP_INET_INGRESS`, `BPF_CGROUP_SOCK_OPS` 같은 cgroup program type에서만 사용할 수 있습니다.
- `BPF_MAP_TYPE_CGRP_STORAGE`는 둘 이상의 cgroup에 local storage를 제공하지만, deprecated map은 BPF program이 attach된 cgroup 하나만 지원합니다.
- `BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`는 attach time에 local storage를 할당하므로 `bpf_get_local_storage()`가 항상 non-NULL storage를 반환합니다. 새 map은 runtime에 할당하므로 `bpf_cgrp_storage_get()`이 NULL을 반환할 수 있습니다. 이 문제를 피하려면 BPF program을 attach하기 전에 userspace에서 `bpf_map_update_elem()`을 호출해 local storage를 미리 할당할 수 있습니다.
- `BPF_MAP_TYPE_CGRP_STORAGE`는 BPF program이 local storage를 삭제할 수 있지만, deprecated map은 program detach 시점에만 storage를 삭제합니다.
전체적으로 `BPF_MAP_TYPE_CGRP_STORAGE`는 `BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED`의 모든 기능과 그 이상의 기능을 지원합니다. 따라서 deprecated map 대신 `BPF_MAP_TYPE_CGRP_STORAGE`를 사용하는 것이 권장됩니다.
요약과 해설
map_cgrp_storage.rst:1-109`BPF_MAP_TYPE_CGRP_STORAGE`는 cgroup별 fixed-size local storage를 제공하며 모든 BPF program type에서 사용할 수 있습니다. Cgroup fd를 key로 조회하고 helper로 program 안에서 storage를 생성하거나 삭제합니다.
Storage가 runtime에 할당되므로 `bpf_cgrp_storage_get()`은 NULL을 반환할 수 있습니다. 반드시 반환 pointer를 검사하거나 attach 전에 userspace에서 storage를 미리 할당해야 합니다.
이 map은 cgroup 하나와 제한된 program type만 지원하던 deprecated `BPF_MAP_TYPE_CGROUP_STORAGE`의 상위 호환 기능을 제공하므로 새 구현에서 우선 사용해야 합니다.