Существует более общий путь. На всех платформах с виртуальными терминалами, включая Linux и BSD, Xserver сохраняет открытый fd к терминалу, на котором он работает. На Linux это остается, хорошее решение для проверки на терминал управления этих X процессов для различения приблизительно X процессов (используйте седьмое поле /proc/<..>/stat
). В более общем плане, хотя, просмотрите список открытого fds этих X процессов, и только требуется некоторую простую фильтрацию для ухода терминала, на котором работает Xserver. (К сожалению, получение списка открытого fds является снова иждивенцем платформы...) Для sysctl
платформы как BSD, код будет выглядеть подобным этому плюс некоторая обработка ошибок:
int ttyByOpenFds(int curPid) {
int ctl[4] = { CTL_KERN, KERN_PROC, KERN_PROC_FILEDESC, curPid };
size_t sizeGuess = 50*sizeof(kinfo_file);
char* buf = malloc(sizeGuess);
int rv = sysctl(ctl, 4, buf, &sizeGuess, 0, 0);
if (rv < 0 && errno == ESRCH) return 0;
else if (rv < 0 && errno == ENOMEM) { /* try again */ }
else if (rv < 0) throw SystemException("unexpected error getting args", errno);
char* position = buf;
while (position < buf + sizeGuess) {
kinfo_file* kfp = reinterpret_cast<kinfo_file*>(position);
position += kfp->kf_structsize;
if (kfp->kf_type != KF_TYPE_VNODE) continue;
if (kfp->kf_vnode_type != KF_VTYPE_VCHR) continue;
if (kfp->kf_fd < 0) continue;
char* name = devname(kfp->kf_un.kf_file.kf_file_rdev, S_IFCHR);
if (!name) continue;
unsigned int ttynum = 0;
if (sscanf(name, "ttyv%u", &ttynum) != 1) continue;
if (ttynum < 8 && kfp->kf_fd <= 2) continue; // stderr going to a console
return ttynum;
}
return 0;
}
Вы хотите сослаться на LV, он - имя а не физический раздел, что это идет.
Вещи структурированы следующим образом. У меня есть 3 вещи:
На моем ноутбуке у меня есть следующее:
$ pvs
PV VG Fmt Attr PSize PFree
/dev/sda6 vg_grinchy lvm2 a- 304.22g 0
Примечание: PV =/dev/sda6, VG = vg_grinchy
$ lvs
LV VG Attr LSize Origin Snap% Move Log Copy% Convert
lv_home vg_grinchy -wi-ao 248.53g
lv_root vg_grinchy -wi-ao 50.00g
lv_swap vg_grinchy -wi-ao 5.69g
Примечание: Так мой VG (vg_grinchy) содержит 3 LVs (lv_home, lv_root, и lv_swap).
Можно подтвердить это с vgs
команда:
$ vgs
VG #PV #LV #SN Attr VSize VFree
vg_grinchy 1 3 0 wz--n- 304.22g 0
Примечание: Посмотрите, что это говорит, что у нас есть #LV = 3, и #PV = 1.
Теперь, если мы используем команду lvdisplay
, мы видим полные имена нашего LVs:
$ lvdisplay |grep "LV Name"
LV Name /dev/vg_grinchy/lv_root
LV Name /dev/vg_grinchy/lv_home
LV Name /dev/vg_grinchy/lv_swap
Это имена, которые необходимо использовать для определения который LV смонтироваться в Вашем grub.cfg
файл.
Ниже одна из моих строк файла конфигурации от моего grub.cfg
файл.
title Fedora (2.6.35.14-106.fc14.x86_64)
root (hd0,4)
kernel /vmlinuz-2.6.35.14-106.fc14.x86_64 ro root=/dev/mapper/vg_grinchy-lv_root rd_LVM_LV=vg_grinchy/lv_root rd_LVM_LV=vg_grinchy/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=l
atarcyrheb-sun16 KEYTABLE=us rhgb quiet
initrd /initramfs-2.6.35.14-106.fc14.x86_64.img
Конечно же, Вы видите, что мое ядро становится переданным следующее:
root=/dev/mapper/vg_grinchy-lv_root
Возможно, вам не хватает файлов устройств для этих разделов. Другими словами:
kpartx -a -v /dev/mgtvg/linux2os
Это должно создать что-то вроде:
/dev/mapper/mgtvg-linux2os1
/dev/mapper/mgtvg-linux2os2
....
После этого вы можете сделать
grub-install /dev/mapper/mgtvg-linux2os
Это в свою очередь разрешит (hd0,0) или (hd0,msdos1) в /dev/mapper/mgtvg-linux2os1, и тогда все может действительно работать.
Обратите внимание, что я бы также сделал все это в chroot. В chroot /dev должны быть VM-узлы устройств от родительской машины, а также /proc. Таким образом, вы будете уверены, что не испортите личинку родительской машины.