1

Я работал с git-репозиториями, клонированными на общем ресурсе samba, около года, и, за исключением нескольких проблем с его настройкой, не было никаких проблем с ним. Недавно я попытался добавить некоторые файлы в существующее хранилище и был удивлен, увидев ошибки "Отказано в доступе".

Теперь я могу инициировать пустое репо, но когда я пытаюсь запустить strace git add test , я получаю:

    open(".git/objects/info/alternates", O_RDONLY|O_NOATIME) = -1 ENOENT (No such file or directory)
    access(".git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391", F_OK) = -1 ENOENT (No such file or directory)
    open(".git/objects/e6/tmp_obj_GvIyn7", O_RDWR|O_CREAT|O_EXCL, 0444) = -1 EACCES (Permission denied)
    write(2, "error: insufficient permission f"..., 88error: insufficient permission for adding an object to repository database .git/objects
    ) = 88
    close(4)                                = 0
    write(2, "error: test: failed to insert in"..., 44error: test: failed to insert into database
    ) = 44
    write(2, "error: unable to index file test"..., 33error: unable to index file test
    ) = 33

Я использую git 1.8.4.2, samba 4.1.1 на 64-битном Archlinux (версия ядра: 3.12.1). Я ничего не менял в конфигурации git и samba с давних пор.

Общий ресурс монтируется с помощью автомонтирования systemd в /etc /fstab:

//SERVER/DATA  /media/smb  cifs user,noauto,credentials=/etc/samba/creds,\
workgroup=PRV,uid=1000,gid=users,_netdev,comment=systemd.automount 0 0

крепление выглядит как:

//SERVER/DATA on /media/smb type cifs (rw,nosuid,nodev,noexec,relatime,vers=1.0,
cache=strict,domain=PRV,uid=1000,forceuid,gid=100,forcegid,addr=10.1.1.5,
file_mode=0755,dir_mode=0755,nounix,serverino,rsize=61440,wsize=65536,actimeo=1)

Разрешения:

    $ ls -lan .git/objects
    total 0
    drwxr-xr-x 2 1000 100 0 11-27 09:04 .
    drwxr-xr-x 2 1000 100 0 2013-11-27  ..
    drwxr-xr-x 2 1000 100 0 11-27 09:39 e6
    drwxr-xr-x 2 1000 100 0 11-27 09:04 info
    drwxr-xr-x 2 1000 100 0 11-27 09:04 pack

    $ ls -lan .git/objects/pack
    total 0
    drwxr-xr-x 2 1000 100 0 11-27 09:04 .
    drwxr-xr-x 2 1000 100 0 11-27 09:04 ..

Я уже попробовал:

  • установка разных разрешений для общего ресурса - тот же результат
  • монтаж вручную - то же самое
  • понижение версии samba и git до более ранних версий - без разницы
  • Судо - это работает, но я не хотел бы использовать его, если это абсолютно необходимо
  • mercurial (из любопытства) - клонирование git-репо не удается, hg-репозитории клонируются без проблем
  • смена владельца и группы после использования sudo - кажется, они остаются неизменными до и после выполнения команды

Что еще я могу сделать, чтобы отладить это? Я довольно склонен оставаться с git, но я не знаю, что не так с разрешениями.

Что касается sudo:

$ touch test
$ sudo strace git add test
open(".git/objects/info/alternates", O_RDONLY|O_NOATIME) = -1 ENOENT (No such file or directory)
access(".git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, ".git/objects/pack", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
getdents(5, /* 2 entries */, 32768)     = 48
getdents(5, /* 0 entries */, 32768)     = 0
close(5)                                = 0
open(".git/objects/e6/tmp_obj_i4e0C8", O_RDWR|O_CREAT|O_EXCL, 0444) = 5
brk(0xd5a000)                           = 0xd5a000
write(5, "x\1K\312\311OR0`\0\0\t\260\1\360", 15) = 15
brk(0xd4a000)                           = 0xd4a000
brk(0xd3a000)                           = 0xd3a000
close(5)                                = 0
link(".git/objects/e6/tmp_obj_i4e0C8", ".git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391") = 0
unlink(".git/objects/e6/tmp_obj_i4e0C8") = 0
lstat(".git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391", {st_mode=S_IFREG|0755, st_size=15, ...}) = 0
close(4)   

$ ls -lan .git/objects/e6
total 1
drwxr-xr-x 2 1000 100  0 11-28 10:11 .
drwxr-xr-x 2 1000 100  0 11-28 10:10 ..
-rwxr-xr-x 1 1000 100 15 11-28 10:11 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
-r-xr-xr-x 1 1000 100  0 11-28 10:11 tmp_obj_9Z8UgU
-r-xr-xr-x 1 1000 100  0 11-28 10:10 tmp_obj_d0yhDJ

Создает объекты с разрешениями 0755 . Без sudo временные объектные файлы остаются с 0555 . Похоже, проблема заключается в создании файла с 0444 качестве обычного пользователя, который, похоже, имеет права на запись во весь репо.

5 ответов5

1

В версии ядра, на которой я работал, была ошибка. Я опустил ядро до 3.11.6 и git add/commit когда пользователь снова начал работать.

1

Это ошибка ядра в 3.12: https://bugzilla.kernel.org/show_bug.cgi?id=66251

Понизьте рейтинг, указанный @bjauy, или обновите до 3.13.

0

Со своей стороны я столкнулся с вышеуказанной проблемой из-за нарушения POSIX в драйвере файловой системы в ядре, используемом в сочетании с Samba. Поскольку я не могу ни использовать sudo ни менять ядро, ни менять Samba-версию, мне нужно было другое решение.

Я не пытался исправить это с помощью локально скомпилированного git , вместо этого я решил исправить это через LD_PRELOAD на лету.

Вы можете найти полный обходной путь на https://github.com/hilbix/misc/tree/master/git_push_samba

Проблемной частью является то, что git создает файл для записи в режиме только для чтения. Это правильно, но с определенной комбинацией неисправного драйвера FS это приводит к сбою системного вызова следующим образом:

open("./objects/98/tmp_obj_vVR5gb", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0444) = -1 EACCES (Permission denied)

Это заставляет git сдаваться. Однако с измененным режимом на 0644 этот системный вызов вернется успешно. Следующий хак это делает:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#define open    ignorethisopen
#define open64  ignorethisopen64
#include <fcntl.h>
#undef open
#undef open64
#include <dlfcn.h>

static int (*___open)(const char *, int, mode_t);
static int (*___open64)(const char *, int, mode_t);

static void *
dlwrap(const char *fn)
{
  const char *err;

  void *p = dlsym(RTLD_NEXT, fn);
  if ((err=dlerror())!=0)
    fprintf(stderr, "dlsym(RTLD_NEXT,'%s'): %s\r\n", fn, err);
  return p;
}

void
_init(void)
{
  DP(("open wrappe"));

  ___open       = dlwrap("open");
  ___open64     = dlwrap("open64");
}

int
open64(const char *file, int flags, mode_t mode)
{
  if (flags && O_CREAT)
    return ___open64(file, flags, mode|0200);
  return ___open64(file, flags, mode);
}

int
open(const char *file, int flags, mode_t mode)
{
  if (flags && O_CREAT)
    return ___open(file, flags, mode|0200);
  return ___open(file, flags, mode);
}

Это должно быть скомпилировано следующим образом:

cc -Wall -O3 -D_GNU_SOURCE -fPIC -c -o git_push_samba.o git_push_samba.c
gcc -o git_push_samba.so -nostartfiles -shared git_push_samba.o -ldl

Впоследствии git можно назвать следующим образом:

LD_PRELOAD=path/to/git_push_samba.so git ...

Заметки:

  • Я назвал это "git_push_samba", потому что я хотел перейти к "голому" git репо, которое находится на общем ресурсе Samba, который был локально подключен к пути. Однако это относится даже к случаю, когда вы обычно работаете с git на такой файловой системе (например, сбой git add ).

  • Может быть несколько других проблем, которые выглядят одинаково. Таким образом, это не решает все варианты этой проблемы, только один, где она возникает из-за неисправного (нарушающего POSIX) драйвера файловой системы.

Как определить, существует ли проблема, которую можно решить следующим образом:

git init testdir
cd testdir
date > README
git add README

Если git add завершается неудачно с "недостаточным разрешением для добавления объекта", это должно решить эту проблему.

0

ваша папка smb видится Linux как в группе "другие". Итак, ваши разрешения должны быть примерно такими, как xx7, например, 777, если вы хотите, чтобы ваш www был доступен для записи для всех групп.

Проблема, каждый раз, когда git создает новую папку, файл или что-то еще, он создает его, используя свои собственные разрешения. Решением является использование umask, поэтому все, что создано на имя текущего пользователя, будет использовать указанные разрешения. В этом случае папка общего доступа Windows вам понадобится:

Umask 000

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

Добавьте этот umask в ваш .bashrc, и проблема решена.

0

Скорее всего, вы внесли изменения в этот репозиторий с правами root, возможно, с помощью sudo , и теперь некоторые файлы в .git принадлежат root. Сделайте chown чтобы восстановить владение файлом для пользователя, которого вы обычно используете.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .