TT Lab
블로그

한국어

시작하기
블로그

블로그

로그에 찍힌 포인터 주소: CDI 의 두 줄짜리 로그 수정이 2일 19시간 만에 병합되기까지

결과: 병합 (2026-10-22 20:19, kubevirt/containerized-data-importer#4320). 사실은 GitHub 의 PR·리뷰·댓글·타임라인·검사 기록, CDI 소스(PR 의 바탕 커밋 9cd4fbdb), Go 표준 라이브러리 문서, 기여 원장의 초안에서 가져왔습니다. 시각은 한국 시간입니다.

목차

한 줄 요약

PR kubevirt/containerized-data-importer#4320 Log the storage class name, not its pointer, in filesystem overhead
바꾼 것 pkg/controller/common/util.go 의 로그 두 줄. 2줄 추가, 2줄 삭제
반응 메인테이너가 16시간 뒤 /approve·/lgtm. 관계없는 e2e 실패 하나를 설명하자 메인테이너가 override
결과 PR 공개 10-20 00:49 → 승인 17:05 → override 10-22 16:42 → 병합 20:19, 약 2일 19시간 30분

1. 무엇이 문제였나: 코드를 읽다 본 두 줄

이번 것은 운영에서 본 로그가 아닙니다. 이 블로그의 「KubeVirt 소스 코드 읽기」 시리즈를 쓰며 CDI 의 크기 계산을 따라가다가, 기여 원장의 「코드 읽기가 찾은 기여 후보」 목록에 다섯째로 적어 둔 것입니다. 이 로그는 8편에서 다룬 파일시스템 여분의 값을 스토리지 클래스마다 고르는 함수 안에 있습니다.

GetFilesystemOverheadForStorageClass 는 스토리지 클래스를 찾지 못하면 기본 클래스를 찾아보고, 그것도 없으면 전역 여분을 씁니다. 그 두 갈림길에서 상세 수준 3(-v=3) 로그를 남깁니다. PR 본문에 적은 출력은 이랬습니다.

Storage class0x7035abda0020not found, trying default storage class

스토리지 클래스 이름 자리에 메모리 주소가 있고, 앞뒤 띄어쓰기도 없습니다. 고친 뒤에는 이렇게 찍힙니다.

Storage class "local-path" not found, trying default storage class

PR 본문에는 이 출력을 재현했다고 적었지만, 기여 원장에는 그 재현의 원본 출력이 남아 있지 않습니다. 위 두 줄은 PR 본문의 예시를 옮긴 것입니다. TT Lab 클러스터의 CDI 가 상세 수준 3 으로 돌고 있는지도 확인하지 않았습니다(미확인).

2. 원인: 소스의 어느 줄인가

줄 번호는 PR 의 바탕 커밋 9cd4fbdb 기준입니다.

storageClassName 은 *string 입니다. 쿠버네티스 API 에서 「비어 있을 수 있는 문자열」을 포인터로 받는 일이 흔해서 생기는 실수로 보입니다. 두 가지가 겹쳐 위 출력이 나옵니다.

  1. klog.Info 는 인자를 fmt.Sprint 방식으로 잇습니다. Go 의 fmt.Sprint 문서는 「두 피연산자가 모두 문자열이 아닐 때만 그 사이에 공백을 넣는다」고 적습니다. "Storage class" 와 포인터 사이, 포인터와 "not found…" 사이는 한쪽이 문자열이라 공백이 들어가지 않습니다.
  2. %v 로 포인터를 찍으면 가리키는 값이 아니라 주소가 나옵니다. 그래서 0x7035abda0020 같은 값이 이름 자리에 들어갑니다.

Info 를 Infof 로 바꾸고 형식 문자열을 주면 공백 문제는 사라집니다. 포인터는 역참조해야 하는데, nil 일 수도 있으니 이 파일이 이미 가져오고 있던 k8s.io/utils/ptr 의 ptr.Deref(storageClassName, "") 를 썼습니다.

3. 무엇을 바꿨나: diff 요지

 	targetStorageClass, err := GetStorageClassByNameWithK8sFallback(ctx, client, storageClassName)
 	if err != nil || targetStorageClass == nil {
-		klog.V(3).Info("Storage class", storageClassName, "not found, trying default storage class")
+		klog.V(3).Infof("Storage class %q not found, trying default storage class", ptr.Deref(storageClassName, ""))
 ...
 	if targetStorageClass == nil {
-		klog.V(3).Info("Storage class", storageClassName, "not found, continuing with global overhead")
+		klog.V(3).Infof("Storage class %q not found, continuing with global overhead", ptr.Deref(storageClassName, ""))

%q 를 고른 것은 이름이 빈 문자열일 때도 "" 로 보이게 하려는 뜻입니다. 같은 함수에 있는 「기본 스토리지 클래스가 없다」 로그는 인자가 문자열 하나라 문제가 없어서 그대로 두었습니다. PR 본문에는 로그만 바꾸는 변경이라는 것과 확인한 것을 적었습니다. go vet ./pkg/controller/common/ 은 깨끗했고, go test ./pkg/controller/common/ 은 43개 모두 통과했습니다(golang:1.27.2 컨테이너, -mod=vendor). 이슈는 따로 열지 않고 「코드를 읽다 찾았다」고 적었습니다.

AI 사용은 커밋 꼬리말 Assisted-by: Claude 와 DCO 서명, 본문 끝의 「Claude 의 도움으로 찾고 고쳤고, 검토하고 위 로그 출력을 재현했다」는 문단으로 밝혔습니다. 이 커밋도 GitHub 에서는 서명되지 않은 커밋으로 보입니다. 원칙 3 의 SSH 서명이 빠진 것으로 보입니다.

4. 반응: 승인은 16시간, 그다음은 e2e 하나

시각 일
10-20 00:49 PR 공개. prow 가 release-note-none·size/XS 라벨, 리뷰어 둘 지정
10-20 17:05 메인테이너가 리뷰로 /approve·/lgtm 과 감사 한마디. lgtm·approved 라벨
10-21 22:23 우리가 /retest-required 를 쳤으나, 봇이 「신뢰되지 않은 작성자는 시험을 직접 걸 수 없다」고 답
10-22 01:05 실패한 검사의 내용을 적어 재시험을 부탁하는 댓글
10-22 16:42 메인테이너가 /override pull-containerized-data-importer-e2e-ceph-wffc
10-22 20:19 tide 가 병합

승인은 빨랐습니다. 두 줄이고, 고치기 전과 뒤의 로그를 나란히 보여 주었으니 따로 물을 것이 없었던 것으로 보입니다. 이 메인테이너는 7편과 6편의 리뷰어와 같은 사람입니다.

승인 뒤에 병합을 막은 것은 e2e 묶음 e2e-ceph-wffc 였습니다. 이름으로 보아 ceph 저장소와 늦은 바인딩(WaitForFirstConsumer)으로 도는 묶음으로 보입니다. 실패는 한 개였고, DataImportCron … with snapshot sources [test_id:10033] 라는 시험이었습니다. 546개 중 545개가 통과했습니다. 로그 문자열 두 개를 바꾼 변경이 스냅숏 소스의 DataImportCron 시험을 깨뜨릴 길은 없어 보였습니다.

그래서 먼저 재시험 명령 /retest-required 를 쳤는데, prow 는 외부 작성자의 명령이라며 받지 않았습니다. 이 저장소는 신뢰되지 않은 작성자가 /ok-to-test 로 시험을 열 수도, 다시 돌릴 수도 없습니다. 몇 시간 뒤 실패한 시험의 이름과 545/546 이라는 숫자를 적고, 이 변경이 그 시험과 닿지 않는다는 것을 한 문장으로 설명한 다음 누군가 재시험을 걸어 달라고 부탁했습니다. 메인테이너는 재시험 대신 그 검사를 override 했고, 네 시간 뒤 병합되었습니다.

5. 배운 것: 오픈소스 기여 요령

티티 한마디. 「○○ 창고를 못 찾았어요」라고 적어야 할 메모장에 창고 이름 대신 「서랍 7035번」이라고, 그것도 띄어쓰기 없이 적혀 있었어요. 이름이 적힌 쪽지를 서랍에 넣어 두고는 서랍 번호만 베껴 쓴 거죠. 쪽지를 꺼내 이름을 읽어 적게 바꿨더니 금방 「좋아요」를 받았어요. 그런데 옆 반 시험지 한 장이 틀려서 기다려야 했고, 저는 다시 채점해 달라는 말도 할 수 없었어요. 그래서 「틀린 문제는 이거고 제 메모와는 상관없어요」라고 적어 드렸더니, 선생님이 그 시험지를 넘겨 주셨어요.

링크

모든 자료는 2026-10-29 에 열람했습니다.

로그인하면 좋아요를 누를 수 있습니다

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다