LINUX.ORG.RU

Забавное поведение mount

 ,


0

2

Добрый день. Недавно я столкнулся со следующей проблемой: имеется программа prog1, в которой исполняется код (упрощенно, но смысл понятен)

int commandExecute(string command,string* ret){
    string d;
    char s[1000];
    FILE* f=popen(command.c_str(),"r");
    while(fgets(s,1000,f)!=0){
        ret->append(&s[0]);
    }
    pclose(f);

    if(ret->size()==0){
        return -1;
    }
    return 0;
}

int main(){
    string ret;
    commandExecute("mount /dev/sdb1 /home/user/MP",&ret);
    printf(ret.c_str());
    ret="";
    commandExecute("/usr/bin/prog0 /home/user/MP",&ret);
    ret="";
    commandExecute("umount /dev/sdb1",&ret);
    return 0;
}
Если вызывать от root'a, то все работает как и должно- раздел монтируется, исполняется prog0 и раздел размонтируется.
Но хотелось бы исполнять prog1 от имени обычного юзера. Для этого написан демон, который через named pipe получает команду и выполняет:
int commandExecute(string command,string* ret){
    string d;
    char s[1000];
    FILE* f=popen(command.c_str(),"r");
    while(fgets(s,1000,f)!=0){
        ret->append(&s[0]);
    }
    pclose(f);

    if(ret->size()==0){
        return -1;
    }
    return 0;
}
......

commandExecute("/usr/bin/prog1",&ret);

......

При этом все работает, как и было задумано. За исключением того, что во время работы prog0 раздел /dev/sdb1 не виден ни в mtab ни в выводе mount, а так же его содержимое не видно в точке монтирования /home/user/MP.
А вот, собственно и вопрос- чем можно объяснить такое поведение mount?

не проще ли sudoers подкрутить?

bvn13 ★★★★★ ()
Ответ на: комментарий от DELIRIUM

вывод strace для prog1

execve("/usr/bin/trs-utils", ["trs-utils", "--mount", "ROOT"], [/* 41 vars */]) = 0
brk(0)                                  = 0xe99000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=207448, ...}) = 0
mmap(NULL, 207448, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7440ec6000
close(3)                                = 0
open("/usr/lib/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\265\5\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=979080, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7440ec5000
mmap(NULL, 3159072, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f74409d6000
mprotect(0x7f7440abc000, 2093056, PROT_NONE) = 0
mmap(0x7f7440cbb000, 40960, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xe5000) = 0x7f7440cbb000
mmap(0x7f7440cc5000, 82976, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7440cc5000
close(3)                                = 0
open("/usr/lib/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200U\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1059264, ...}) = 0
mmap(NULL, 3154264, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f74406d3000
mprotect(0x7f74407d4000, 2097152, PROT_NONE) = 0
mmap(0x7f74409d4000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x101000) = 0x7f74409d4000
close(3)                                = 0
open("/usr/lib/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260*\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=89000, ...}) = 0
mmap(NULL, 2184800, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f74404bd000
mprotect(0x7f74404d2000, 2097152, PROT_NONE) = 0
mmap(0x7f74406d2000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x7f74406d2000
close(3)                                = 0
open("/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2031215, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7440ec4000
mmap(NULL, 3840528, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7440113000
mprotect(0x7f74402b3000, 2097152, PROT_NONE) = 0
mmap(0x7f74404b3000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a0000) = 0x7f74404b3000
mmap(0x7f74404b9000, 14864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f74404b9000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7440ec3000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7440ec1000
arch_prctl(ARCH_SET_FS, 0x7f7440ec1740) = 0
mprotect(0x7f74404b3000, 16384, PROT_READ) = 0
mprotect(0x7f74409d4000, 4096, PROT_READ) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7440ec0000
mprotect(0x7f7440cbb000, 32768, PROT_READ) = 0
mprotect(0x7f7440ef9000, 4096, PROT_READ) = 0
munmap(0x7f7440ec6000, 207448)          = 0
brk(0)                                  = 0xe99000
brk(0xeba000)                           = 0xeba000
open("/etc/trs/trs.cfg", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=332, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7440ef8000
read(3, "[ROOT]\nTRS_PROFILE_TYPE=disk\nTRS"..., 4096) = 332
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0x7f7440ef8000, 4096)            = 0
pipe2([3, 4], O_CLOEXEC)                = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f7440ec1a10) = 21770
close(4)                                = 0
fcntl(3, F_SETFD, 0)                    = 0
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7440ef8000
read(3, "/dev/sdb1\n", 4096)            = 10
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21770, si_status=0, si_utime=0, si_stime=0} ---
read(3, "", 4096)                       = 0
close(3)                                = 0
wait4(21770, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 21770
munmap(0x7f7440ef8000, 4096)            = 0
pipe2([3, 4], O_CLOEXEC)                = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f7440ec1a10) = 21771
close(4)                                = 0
fcntl(3, F_SETFD, 0)                    = 0
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7440ef8000
read(3, "", 4096)                       = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21771, si_status=0, si_utime=0, si_stime=0} ---
close(3)                                = 0
wait4(21771, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 21771
munmap(0x7f7440ef8000, 4096)            = 0
exit_group(0)                           = ?
+++ exited with 0 +++

CreepingDeath ()
Ответ на: комментарий от CreepingDeath

Ты неправильно вызываешь strace. Без ключа -f он в данном случае бесполезен. И не надо сюда портянки постить. Лучше выложи на какой-нибудь paste-хостинг.

DELIRIUM ☆☆☆☆☆ ()
mount("/dev/sdb1", "/home/ms/TRS_MP", "ext4", MS_MGC_VAL, NULL) = 0

Где-то ты врёшь. mount() отрабатывает в обоих случаях одинаково.

Попробуй сделать минимальный тест-кейс без всяких твоих commandExecute().

1 случай: «обычная программа» делает вызов mount()

2 случай: твой демон делает напрямую вызов mount()

DELIRIUM ☆☆☆☆☆ ()
Ответ на: комментарий от DELIRIUM

вот и я о том же))

я пробовал переносить кусок кода из программы в демон, фактически без изменений, заменял commandExecute(«mount ... на

int r=mount("/dev/sdb1","/home/ms/TRS_MP","ext4", MS_MGC_VAL, NULL)
игрался с параметрами вызова mount, все без толку-эффект тот же. Прога отрабатывает нормально, но нигде не видно смонтированного раздела.

Поэтому, собственно и запостил вопрос. Впечатление такое, что когда вызывается из демон->тред->mount, то монтируется куда то в ramfs или хз куда.

К стати, во время работы prog0 активно юзает /tmp, без чего нормальная работа невозможна. Но при вызове из демона в tmp, так же ничего не появляется.

CreepingDeath ()
Ответ на: комментарий от CreepingDeath

скорее вы ищите отсутсвующую черную кошку в темной комнате и зря фантазируете про mount. Программам тупо нехватило прав для работы в смонтированном рутом каталоге

- Что там у вас с правами на /home/ms/TRS_MP, prog0, prog1, «демона»?

- из чего вы заключили что «во время работы prog0 раздел /dev/sdb1 не виден ни в mtab ни в выводе mount, а так же его содержимое не видно в точке монтирования /home/user/MP.» ?

- факты " во время работы prog0 активно юзает /tmp, без чего нормальная работа невозможна. Но при вызове из демона в tmp, так же ничего не появляется. " и «Прога отрабатывает нормально» вообще-то взаимоисключающие. Либо вы плохо смотрели, либо программа работает всё же ненормально, либо срёт временные файлы не в /tmp

MKuznetsov ★★★★★ ()
Ответ на: комментарий от MKuznetsov

- из чего вы заключили что «во время работы prog0 раздел /dev/sdb1 не виден ни в mtab ни в выводе mount, а так же его содержимое не видно в точке монтирования /home/user/MP.» ?

время работы prog0 несколько десятков минут, так что хватает времени и наутилусом по папкам полазить и вывод mount посмотреть.

- факты " во время работы prog0 активно юзает /tmp, без чего нормальная работа невозможна. Но при вызове из демона в tmp, так же ничего не появляется. " и «Прога отрабатывает нормально» вообще-то взаимоисключающие. Либо вы плохо смотрели, либо программа работает всё же ненормально, либо срёт временные файлы не в /tmp

в tmp распаковывается архив с данными из /dev/sdb1, на основании которых prog0 обрабатывает данные на разделе sdb1 и затем упаковывает результат в архив и возвращает на sdb1.

Новые архивы появляются. Данные в них корректны. Значит прога работает. Путь /tmp жестко прописан в коде программы. Но во время работы в /tmp ничего нет, как я и говорил.

CreepingDeath ()

не виден ни в mtab ни в выводе mount

Это одно и то же. Лучше смотреть /proc/mounts (хотя mtab может быть ссылкой на него).

xeiph ()
Ответ на: комментарий от CreepingDeath

дык что там с правами ? и umask непомешает..

время работы prog0 несколько десятков минут, так что хватает времени и наутилусом по папкам полазить и вывод mount посмотреть.

а про отладчик мыслей не возникало ?

MKuznetsov ★★★★★ ()
Ответ на: комментарий от MKuznetsov

umask(0); setsid(); chdir(«/»);

это из кода демона.

демон запускается от рута. права на TRS_MP 0777. mtab ссылка на /proc/mounts

а про отладчик мыслей не возникало ?

возникало. ставил логирование в разных местах и писал в логи значения переменных. Все работает как задумано. а отладчиком не представлю как зацепиться, чтоб из треда порожденного тредом-listener'ом оттрейсить прогу вызваную через popen.

короче, надо чето упрощать я думаю. а то мистика какая то

CreepingDeath ()
Ответ на: комментарий от CreepingDeath

Странное дело. Если демона запускать через systemctl start, то mount в popen не работает. А если запустить просто из терминала то все ОК.

CreepingDeath ()
Ответ на: комментарий от CreepingDeath

Все. Проблема решена. Дело было в параметрах в файле mydaemon.service, а именно PrivateTmp=true. После удаления которого, все заработало.

Всем спасибо, кто откликнулся

CreepingDeath ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.