2007/02/23

Solaris 에서 read_vtoc()의 사용

솔라리스는 예전의 작은 디스크들의 레이블로 SMI label을 사용했었는데요. 스토리지가 커지면서 LUN 기반의 스토리지나 zfs와 같은 초대형 스토리지 및 화일 시스템을 지원하기 위해서 EFI label이라는 것이 새로 생겼습니다.

read_vtoc() 시스템 콜은 예전에 SMI로 label 되었거나 새로운 Label인 EFI중의 2**32-1보다 작은 블록을 가진 디스크에 대해서만 사용할 수 있게되어 있으며, 새로이 EFI label을 사용하는 스토리지나 디스크의 경우에는 efi 인터페이스를 사용해서 vtoc를 읽어오도록 되어 있습니다.

즉, read_vtoc를 사용했다면 대신에 efi_alloc_and_init(3EXT)을 사용해서 소스를 새로이 변경하셔야 합니다.
코딩은 다음의 소스를 참고해서 작성하시면 될 겁니다. 다음은 i_label의 디스크를 읽는 방법을 담은 소스(opensolaris.org에서 퍼옴)입니다. 참고삼아, 작성하시길 바랍니다.

아래 소스 코드에는 없습니다만 efi_alloc_and_read로 vtoc를 리턴받으신 후 사용하신 후에는 반드시 efi_free()로 해당 vtoc를 free 시키셔야 합니다. 참고 man efi_alloc_and_read.3ext

도움이 되셨다면 위의 광고 한번 살짝 클릭해주세요.

630 * readefi(): Read a partition map.
631 */
632 static int
633 readefi(int fd, char *name, struct dk_gpt **efi)
634 {
635 int retval;
636
637 if ((retval = efi_alloc_and_read(fd, efi)) >= 0)
638 return (0);
639
640 switch (retval) {
641 case (VT_EIO):
642 return (warn(name, "Unable to read VTOC"));
643 case (VT_EINVAL):
644 return (warn(name, "Invalid VTOC"));
645 case (VT_ERROR):
646 return (warn(name, "Unknown problem reading VTOC"));
647 }
648 return (retval);
649 }

/* 내부 작동 원리 : libelf */
203 efi_alloc_and_read(int fd, struct dk_gpt **vtoc)
204 {
205 int rval;
206 uint32_t nparts;
207 int length;
208
209 /* figure out the number of entries that would fit into 16K */
210 nparts = EFI_MIN_ARRAY_SIZE / sizeof (efi_gpe_t);
211 length = (int) sizeof (struct dk_gpt) +
212 (int) sizeof (struct dk_part) * (nparts - 1);
213 if ((*vtoc = calloc(length, 1)) == NULL)
214 return (VT_ERROR);
215
216 (*vtoc)->efi_nparts = nparts;
217 rval = efi_read(fd, *vtoc);
218
219 if ((rval == VT_EINVAL) && (*vtoc)->efi_nparts > nparts) {
220 void *tmp;
221 length = (int) sizeof (struct dk_gpt) +
222 (int) sizeof (struct dk_part) *
223 ((*vtoc)->efi_nparts - 1);
224 nparts = (*vtoc)->efi_nparts;
225 if ((tmp = realloc(*vtoc, length)) == NULL) {
226 free (*vtoc);
227 *vtoc = NULL;
228 return (VT_ERROR);
229 } else {
230 *vtoc = tmp;
231 rval = efi_read(fd, *vtoc);
232 }
233 }
234
235 if (rval < 0) {
236 if (efi_debug) {
237 (void) fprintf(stderr,
238 "read of EFI table failed, rval=%d\n", rval);
239 }
240 free (*vtoc);
241 *vtoc = NULL;
242 }
243
244 return (rval);
245 }