On Mon, Jan 16, 2017 at 06:44:04PM +0100, Theo Buehler wrote:
> > The chown(1) error is due to my user (semarie) isn't member of wobj group
> > (I only use snapshot on this host for upgrading).
> > 
> > This requirement for a build outside /usr/src seems a bit odd to me.
> > Do I miss something ?
> 
> With a newly installed system (after Nov 25) you would not be able to do
> 'make obj' inside /usr/src either. It was mentioned on current.html that
> 
>   Developers MUST add their users to the group wobj, so that they can
>   still write to /usr/{,x}obj
> 
> and this applies to this situation as well.  One of the requirements of
> having the dedicated build user was that 'make build' also works for
> source trees based outside /usr/src.  Since two different users need to
> be able to write to the same location (obj/), there seems no way around
> adding them both to the same group.

I am still not fully convinced :)

But it is just possible I missunderstand that I could use bsd.prog.mk
for my personals projects without using BUILDUSER.

For now, let's go in bsd.obj.mk:

    17  obj! _SUBDIRUSE
    18          @cd ${.CURDIR}; \
    19          umask ${WOBJUMASK}; \
    20          here=`/bin/pwd`; bsdsrcdir=`cd ${BSDSRCDIR}; /bin/pwd`; \
    21          subdir=$${here#$${bsdsrcdir}/}; \

the obj target has defined 3 (shell) variables:
  - here: the current directory
  - bsdsrcdir: the real directory for /usr/src
  - subdir: it will be the subdir part of the path if .CURDIR is under
    $bsdsrcdir, or same as $here.

The next `if' tries to define how SETOWNER will be defined.

If I correctly understand the code:

  - when runs as root (and BUILDUSER isn't defined to "root"), makes
    SETOWNER to change the ownership to the BUILDUSER.

    and if working under /usr/src, makes mkdir to be done by BUILDUSER
    (using su).

    22          if [[ `id -u` -eq 0 && ${BUILDUSER} != root ]]; then \
    23                  SETOWNER="chown -h ${BUILDUSER}:${WOBJGROUP}"; \
    24                  if [[ $$here != $$subdir ]]; then \
    25                          _mkdirs() { \
    26                                  su ${BUILDUSER} -c "mkdir -p $$1"; \
    27                          }; \
    28                          MKDIRS=_mkdirs; \
    29                  fi; \

  - when the make occurs somewhere else than under /usr/src, makes
    SETOWNER to change the group to wobj.

    30          elif [[ $$here == $$subdir ]]; then \
    31                  SETOWNER="chown :${WOBJGROUP}"; \
    32          else \

  - when the make occurs under /usr/src, makes SETOWNER to do nothing.

    33                  SETOWNER=:; \
    34          fi; \

For now, I just wonder if the elif at line 30 isn't simply inversed: it
makes more sens to me to enforce "chown :wobj" when build occurs under
/usr/src.

But we could continue:

    35          [[ -z $$MKDIRS ]] && MKDIRS="mkdir -p"; \

Here it is the default way to make directory. Previously, only in "make
runs as root" there is alternative definition.


In the next block we go back in conditional based on location of the
build.

    36          if test $$here != $$subdir ; then \

Here, it is when the build occurs somewhere under /usr/src.

    37                  dest=${BSDOBJDIR}/$$subdir ; \
    38                  echo "$$here/${__objdir} -> $$dest"; \

The default location of the build-directory is /usr/obj/$subdir

The next block ensures that "obj/" is already a link to /usr/obj/$subdir
or it will create the link (eventually removing previous local "obj/"
node). It does nothing regarding existence of the target: it is just the
link that is created.

Also, please note that when run as normal user, SETOWNER is ":" in this
particular case. And when runs as root, the chown has -h, so the link
will be owned by BUILDUSER.

    39                  if test ! -L ${__objdir} -o \
    40                      X`readlink ${__objdir}` != X$$dest; \
    41                      then \
    42                          if test -e ${__objdir}; then rm -rf 
${__objdir}; fi; \
    43                          ln -sf $$dest ${__objdir}; \
    44                          $$SETOWNER ${__objdir}; \
    45                  fi; \

Next is the creation of the directory (before, we just create a link to
it, without checking first if exists or not). The directory owner isn't
setted after creation of the build directory.

    46                  if test -d ${BSDOBJDIR}; then \
    47                          test -d $$dest || $$MKDIRS $$dest; \
    48                  else \
    49                          if test -e ${BSDOBJDIR}; then \
    50                                  echo "${BSDOBJDIR} is not a directory"; 
\
    51                          else \
    52                                  echo "${BSDOBJDIR} does not exist"; \
    53                          fi; \
    54                  fi; \


The next block is for creation of "obj/" when the make occurs outside
/usr/src. It is simple: call mkdir, et next change ownership to
WOBJGROUP.

    55          else \
    56                  true ; \
    57                  dest=$$here/${__objdir} ; \
    58                  if test ! -d ${__objdir} ; then \
    59                          echo "making $$dest" ; \
    60                          $$MKDIRS $$dest; \
    61                          $$SETOWNER $$dest; \
    62                  fi ; \
    63          fi;


After reading the code, some points bother me:

  - in case of user build (not root) and under /usr/src, the use of
    BUILDUSER isn't required, whereas it is when build occurs outside
    /usr/src.

    in case of root building, the mkdir is done using su, so the build
    directory will be owned by BUILDUSER.

  - when build occurs under /usr/src, the logic is:
     - create the link (and chown the link if root)
     - mkdir the obj/ without care the owner (but if root, use su to
       mkdir).

    the order of operation seems a bit odd. I would create the
    directory, change owner if under /usr/src, and next create the link.


It could be confirmed by testing

with an empty /usr/obj directory, no "obj/", and my user isn't member
of wobj:

$ cd /usr/src/bin/ls
$ make obj
$ ls -ld obj
lrwxrwx---  1 semarie  semarie  15 Jan 16 19:59 obj@ -> /usr/obj/bin/ls
$ ls -ld obj/
drwxrwx---  2 semarie  wsrc  512 Jan 16 20:20 obj//

No error showed when running "make obj" (same command outside /usr/src
will generate error due to "chown :wobj").

(The "wsrc" on /usr/obj/bin/ls is due to group owner of /usr/obj -
something I should change I think, but it is unrevelant).

So I still think there is a problem somewhere.

Thanks.
-- 
Sebastien Marie

Reply via email to