systemd multiuser.target을 실행하기 위한 debian grub 사용자 정의 항목을 만듭니다.

systemd multiuser.target을 실행하기 위한 debian grub 사용자 정의 항목을 만듭니다.

Debian Stretch가 있고 그래픽 데스크탑 없이 시스템을 실행하기 위한 사용자 정의 Grub 항목을 원합니다. 나는 그것이 다른 런레벨을 실행하는 것만큼 간단하다고 생각했지만, 그것에 대해 읽고 나서 systemd모든 것이 다르다는 것을 깨달았습니다.

읽고 나서이 문제Red Hat 소개 및이 다른Debian Jessie의 경우 대상에 대해 알게 되었고 systemd내가 하고 싶은 일은 multi-user.target에서 실행되는 것이라고 생각했습니다.

찾았어요이 페도라 링크,이 아치리눅스 커널링크와또 다른. 그들은 둘 다 grub 메뉴 항목의 "linux" 줄에 추가할 수 있는 "systemd.unit" 옵션이 있다고 설명했습니다. 그래서 사용자 정의 메뉴 항목을 만드는 방법을 설명하는 링크를 검색했습니다.이것. 그러나 grub 화면에서 "e" 키를 사용하여 내 자동 grub 항목을 살펴보면 링크에 있는 항목보다 더 복잡합니다. 문제는 사용자 정의 메뉴 항목의 모든 내용을 복사해야 하는지 알 수 없다는 것입니다.

 setparams 'Debian gnu/linux, con linux 4.8.0-2-amd64'
 load_video
 insmod gzio
 if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
 insmod part-msdos
 insmod ext2
 set root='hd0,msdos5'
 if [ x$feature_platform_search_hint = xy ]; then
    search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos5 --hint-efi=hd0,msdos5 --hint-baremetal=ahci0,msdos5  3202c741-ef05-40e4-9368-8617e7b1fb3c
else
    search --no-floppy --fs-uuid --set=root 3202c741-ef05-40e4-9368-8617e7b1fb3c
fi
echo 'Cargando Linux 4.8...'
linux /vmlinuz-4.8.0-2-amd64 root=UUID=17f74892-fe09-46ec-91ca-2dca457565a1 ro quiet
echo 'Cargando imagen de memoria inicial...'
initrd /initrd.img-4.8.0-2-amd64

이것은 마지막 코어에 대해 자동으로 생성된 항목입니다. 이 모든 항목을 사용자 정의 메뉴 항목에 복사하고 항목만 변경할 수 있습니다.

linux /vmlinuz-4.8.0-2-amd64 root=UUID=17f74892-fe09-46ec-91ca-2dca457565a1 ro quiet

라인은

linux /vmlinuz-4.8.0-2-amd64 root=UUID=17f74892-fe09-46ec-91ca-2dca457565a1 ro quiet systemd.unit=multi-user.target

?

답변1

며칠간의 연구 Systemd끝에 Grub.

1. 새로운 /etc/grub.d/* 구성 파일을 생성합니다

이를 위해 /etc/grub.d/10_linux파일을 템플릿으로 복사했습니다.

sudo cp /etc/grub.d/10_linux /etc/grub.d/11_multiuser

원본 파일은 최신 커널에 대한 루트 항목과 "고급 옵션" 하위 메뉴를 생성합니다. 그래서 11_multiuser다중 사용자 옵션에 대한 새 하위 메뉴와 다중 사용자 모드의 각 코어에 대한 새 옵션을 만들기 위해 파일을 일부 편집했습니다. 여기에 수정된 줄이 포함된 패치를 추가하겠습니다.

--- /etc/grub.d/10_linux
+++ /etc/grub.d/11_multiuser
@@ -118,6 +118,8 @@
       case $type in
      recovery)
          title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" ;;
+      multiuser)
+          title="$(gettext_printf "%s, with Linux %s (multiuser)" "${os}" "${version}")" ;;
      init-*)
          title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "${type#init-}")" ;;
      *)
@@ -227,57 +229,18 @@
 boot_device_id=
 title_correction_code=

-cat << 'EOF'
-function gfxmode {
-   set gfxpayload="${1}"
-EOF
-if [ "$vt_handoff" = 1 ]; then
-  cat << 'EOF'
-   if [ "${1}" = "keep" ]; then
-       set vt_handoff=vt.handoff=7
-   else
-       set vt_handoff=
-   fi
-EOF
-fi
-cat << EOF
-}
-EOF
-
-# Use ELILO's generic "efifb" when it's known to be available.
-# FIXME: We need an interface to select vesafb in case efifb can't be used.
-if [ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 0 ]; then
-  echo "set linux_gfx_mode=$GRUB_GFXPAYLOAD_LINUX"
-else
-  cat << EOF
-if [ "\${recordfail}" != 1 ]; then
-  if [ -e \${prefix}/gfxblacklist.txt ]; then
-    if hwmatch \${prefix}/gfxblacklist.txt 3; then
-      if [ \${match} = 0 ]; then
-        set linux_gfx_mode=keep
-      else
-        set linux_gfx_mode=text
-      fi
-    else
-      set linux_gfx_mode=text
-    fi
-  else
-    set linux_gfx_mode=keep
-  fi
-else
-  set linux_gfx_mode=text
-fi
-EOF
-fi
-cat << EOF
-export linux_gfx_mode
-EOF
-
 # Extra indentation to add to menu entries in a submenu. We're not in a submenu
 # yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
 submenu_indentation=""

-is_top_level=true
+# para el menu de multiuser
+submenu_indentation="$grub_tab"
+if [ -z "$boot_device_id" ]; then
+  boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
+fi
+gettext_printf "Agregando entradas multiuser...\n" >&2
+echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote) (MultiUser)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
+is_top_level=false
 while [ "x$list" != "x" ] ; do
   linux=`version_find_latest $list`
   case $linux in
@@ -331,34 +294,9 @@
     linux_root_device_thisversion=${GRUB_DEVICE}
   fi

-  if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
-    linux_entry "${OS}" "${version}" simple \
-    "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
-
-    submenu_indentation="$grub_tab"
-    
-    if [ -z "$boot_device_id" ]; then
-   boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
-    fi
-    # TRANSLATORS: %s is replaced with an OS name
-    echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
-    is_top_level=false
-  fi
-
-  linux_entry "${OS}" "${version}" advanced \
-              "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
-
-  for supported_init in ${SUPPORTED_INITS}; do
-    init_path="${supported_init#*:}"
-    if [ -x "${init_path}" ] && [ "$(readlink -f /sbin/init)" != "${init_path}" ]; then
-      linux_entry "${OS}" "${version}" "init-${supported_init%%:*}" \
-         "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} init=${init_path}"
-    fi
-  done
-  if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
-    linux_entry "${OS}" "${version}" recovery \
-                "${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}"
-  fi
+  linux_entry "${OS}" "${version}" multiuser \
+              "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} systemd.unit=multi-user.target"
+

   list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`
 done

이 솔루션을 사용하면 코어를 추가/제거하거나 grub 메뉴 재구성과 관련된 작업을 수행하면 필요한 다중 사용자 항목이 각 코어에 자동으로 추가됩니다. 또한 grub을 업데이트하면 새 프로필이 11_multiuserGrub의 사전 정의된 프로필의 일부가 아니기 때문에 삭제되지 않을 것이라고 생각합니다(완전히 확실하지는 않습니다).

2. /etc/grub.d/10_linux 파일 수정

여기에 또 다른 접근 방식이 있지만 첫 번째 접근 방식보다 더 나쁘다고 생각합니다. 이렇게 하면 공식 파일을 수정하므로 Grub의 구성과 전체 시스템의 시작이 중단될 수 있습니다. 또한 업데이트로 인해 파일이 교체되면 구성이 손실될 수 있습니다. 여기에는 단 한 가지 장점이 있습니다. 고급 옵션 하위 메뉴에 다중 사용자 항목을 삽입할 수 있다는 것입니다. 이 부분에는 첫 번째 방법에 추가된 패치가 유효합니다. 어쨌든 나는 이 접근법에 전적으로 동의하지 않는다.

3. /etc/grub.d/40_custom 파일 수정

이 파일은 특정 항목을 삽입하도록 설계되었습니다. 해당 항목을 이 파일에 복사하여 /boot/grub/grub.cfg붙여넣고 systemd를 추가할 수 있습니다. 완전히 괜찮지만 문제는 원하는 모든 코어에 대해 이 작업을 수행해야 한다는 것입니다. 또한 새 커널이 시스템에 제거/추가될 때 이 파일을 수동으로 유지 관리해야 합니다. 또한 이러한 항목은 grub 메뉴 끝에 나타나므로 다른 운영 체제(예: Windows)를 사용하는 경우 사용자 정의 항목은 첫 번째 Linux 항목과 구분됩니다.

답변2

원래 게시물 이후 5년이 지났으니 이제 또 다른 답변을 내놓아야 할 때가 된 것 같습니다.

귀하(또는 다른 사람들)가 이전 커널을 포함하는 사용자 정의 메뉴 항목이 필요하지 않은 경우 해결책이 곧 나올 것입니다...

  • 코드 수정 방지
  • 정적 메뉴 항목을 사용하면 시스템 업데이트나 grub.cfg 재구축에 관계없이 항상 최신 커널을 반영합니다.
  • 기본 메뉴 항목 뒤, 다른 운영 체제 앞에 그럽 메뉴에 나타나야 합니다.

이전에 데비안을 사용해 본 적이 없기 때문에 이에 대해 잘 모르겠지만, 데비안이 최신 커널과 initrd에 대한 보편적인 이름의 심볼릭 링크를 제공하는 한, 이에 맞게 동화되면 작동할 것입니다. 데비안이 이러한 심볼릭 링크를 제공하지 않으면 종료 시 서비스로 실행되는 스크립트가 필요하며, 필요에 따라 이 작업을 수행하고 현재 커널 및 initrd의 실제 이름을 적용하거나 일반 심볼릭 링크를 생성합니다.

OpenSUSE에서는 /boot/vmlinuz 및 /boot/initrd가 각각 최신 커널 및 initrd에 대한 심볼릭 링크이므로 서비스 없이 수행되는 방법입니다.

sudo cp --preserve /etc/grub.d/40_custom /etc/grub.d/25_custom

# locate and copy the entirety of relevant menu entries from grub.cfg, to 25_custom
sudo vim /boot/grub2/grub.cfg /etc/grub.d/25_custom

# mod menu entries in 25_custom as needed, and retain all lines unless good reason to delete any
# and do the following mods so entries no longer depend on specifically named kernel

# mod line like this...
echo    'Loading Linux 5.16.4-1-default ...'
# ...to be like this
echo    'Loading Linux ...'

# mod line like this...
linux   /boot/vmlinuz-5.16.4-1-default ...
# ...to be like this. the '3' is for multi-user in openSUSE
linux   /boot/vmlinuz ... 3

# mod line like this...
initrd  /boot/initrd-5.16.4-1-default
# ...to be like this
initrd  /boot/initrd

sudo grub2-mkconfig -o /boot/grub2/grub.cfg

재부팅하고 확인하세요.

관련 정보는 여기에 있습니다. 관심이 있으시면...
https://forums.opensuse.org/showthread.php/480353-12-2-New-install-Adding-options-in-grub2-menu
https://help.ubuntu.com/community/Grub2/CustomMenus

관련 정보