diff options
Diffstat (limited to 'package/aufs2-util')
-rw-r--r-- | package/aufs2-util/Makefile | 26 | ||||
-rw-r--r-- | package/aufs2-util/patches/patch-Makefile | 68 | ||||
-rw-r--r-- | package/aufs2-util/src/COPYING | 340 | ||||
-rw-r--r-- | package/aufs2-util/src/Makefile | 93 | ||||
-rw-r--r-- | package/aufs2-util/src/README | 46 | ||||
-rw-r--r-- | package/aufs2-util/src/au_util.h | 67 | ||||
-rwxr-xr-x | package/aufs2-util/src/aubrsync | 304 | ||||
-rwxr-xr-x | package/aufs2-util/src/auchk | 130 | ||||
-rw-r--r-- | package/aufs2-util/src/aufs.in.5 | 1684 | ||||
-rw-r--r-- | package/aufs2-util/src/aufs.shlib | 83 | ||||
-rw-r--r-- | package/aufs2-util/src/auplink.c | 64 | ||||
-rw-r--r-- | package/aufs2-util/src/br.c | 172 | ||||
-rw-r--r-- | package/aufs2-util/src/c2sh.c | 42 | ||||
-rw-r--r-- | package/aufs2-util/src/c2tmac.c | 44 | ||||
-rw-r--r-- | package/aufs2-util/src/compat.h | 34 | ||||
-rw-r--r-- | package/aufs2-util/src/mount.aufs.c | 255 | ||||
-rw-r--r-- | package/aufs2-util/src/mtab.c | 216 | ||||
-rw-r--r-- | package/aufs2-util/src/plink.c | 356 | ||||
-rw-r--r-- | package/aufs2-util/src/proc_mnt.c | 85 | ||||
-rw-r--r-- | package/aufs2-util/src/rdu.c | 749 | ||||
-rwxr-xr-x | package/aufs2-util/src/umount.aufs | 31 |
21 files changed, 63 insertions, 4826 deletions
diff --git a/package/aufs2-util/Makefile b/package/aufs2-util/Makefile index 4078fa8e1..f42767dbe 100644 --- a/package/aufs2-util/Makefile +++ b/package/aufs2-util/Makefile @@ -4,26 +4,44 @@ include $(TOPDIR)/rules.mk PKG_NAME:= aufs2-util -PKG_VERSION:= 130809 +PKG_VERSION:= 2-100111 PKG_RELEASE:= 1 +PKG_MD5SUM:= 1854f5ab560dd375b22f6e2b747cb412 PKG_DESCR:= aufs2 utilities PKG_SECTION:= fs PKG_URL:= http://aufs.sf.net/ +# created from git via: +# $ git archive --format tar aufs2.1 | \ +# gzip -9 -c >../aufs2-util-2-$(date +%d%m%g).tar.gz + +PKG_SITES:= http://nwl.cc/~n0-1/ +WRKDIST= ${WRKDIR} + PKG_HOST_DEPENDS:= !cygwin !freebsd !openbsd !netbsd -NO_DISTFILES:= 1 +PKG_SUBPKGS:= AUFS2_UTIL LIBAU +PKGSD_LIBAU:= aufs2 userspace library include $(TOPDIR)/mk/package.mk $(eval $(call PKG_template,AUFS2_UTIL,${PKG_NAME},${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKG_DESCR},${PKG_SECTION})) +$(eval $(call PKG_template,LIBAU,libau,${PKG_VERSION}-${PKG_RELEASE},${PKG_DEPENDS},${PKGSD_LIBAU},${PKG_SECTION})) CONFIG_STYLE:= manual -MAKE_FLAGS+= KDIR=${LINUX_DIR} +XAKE_FLAGS+= Install=install HOSTCPPFLAGS="-I${LINUX_HEADER_DIR}/include" post-install: $(INSTALL_DIR) $(IDIR_AUFS2_UTIL)/sbin - $(INSTALL_BIN) ${WRKINST}/sbin/{u,}mount.aufs \ + $(INSTALL_BIN) ${WRKINST}/sbin/{{u,}mount.aufs,auplink} \ $(IDIR_AUFS2_UTIL)/sbin + $(INSTALL_DIR) $(IDIR_AUFS2_UTIL)/usr/bin + $(INSTALL_BIN) ${WRKINST}/usr/bin/au{brsync,chk} \ + $(IDIR_AUFS2_UTIL)/usr/bin + $(INSTALL_DIR) $(IDIR_AUFS2_UTIL)/etc/default + $(INSTALL_DATA) ${WRKINST}/etc/default/aufs \ + $(IDIR_AUFS2_UTIL)/etc/default + $(INSTALL_DIR) $(IDIR_LIBAU)/usr/lib + ${CP} ${WRKINST}/usr/lib/libau* ${IDIR_LIBAU}/usr/lib include ${TOPDIR}/mk/pkg-bottom.mk diff --git a/package/aufs2-util/patches/patch-Makefile b/package/aufs2-util/patches/patch-Makefile index 5cfb193c3..d77ea81ec 100644 --- a/package/aufs2-util/patches/patch-Makefile +++ b/package/aufs2-util/patches/patch-Makefile @@ -1,33 +1,47 @@ - - explicitly use the host cc to compile c2sh and c2tmac - (using per-target local variable assignments is an elegant - way for not having to define explicit rules for the targets) - - dont try setting owner and group of installed files ---- aufs2-util-130809.orig/Makefile 2009-08-13 14:59:49.000000000 +0200 -+++ aufs2-util-130809/Makefile 2009-08-23 18:05:03.909726416 +0200 -@@ -54,6 +54,11 @@ ${Dummy}: ${LibSoObj} - ${LibSo}: ${Dummy} - ln -f $< $@ +--- w-aufs2-util-2-100111-1.orig/Makefile 2011-01-07 05:00:54.000000000 +0100 ++++ w-aufs2-util-2-100111-1/Makefile 2011-01-10 23:43:23.000000000 +0100 +@@ -15,6 +15,11 @@ + # along with this program; if not, write to the Free Software + # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c2sh c2tmac: CC = ${HOSTCC} -+c2sh c2tmac: CFLAGS="-I${KDIR}/include" -+c2sh c2tmac: LDFLAGS= -+c2sh c2tmac: CPPFLAGS= ++c2sh c2tmac: CFLAGS= ${HOSTCFLAGS} ++c2sh c2tmac: LDFLAGS= ${HOSTLDFLAGS} ++c2sh c2tmac: CPPFLAGS= ${HOSTCPPFLAGS} -I./libau -I${LINUX_HEADER_DIR}/include + - etc_default_aufs: c2sh aufs.shlib - ${RM} $@ - echo '# aufs variables for shell scripts' > $@ -@@ -86,12 +91,12 @@ install_ulib: File = ${LibSo} - install_ulib: Tgt = ${DESTDIR}/ulib - install_sbin install_ubin install_man install_ulib: ${File} - install -d ${Tgt} -- install -m 755 -o root -g root -p ${Opt} ${File} ${Tgt} -+ install -m 755 -p ${Opt} ${File} ${Tgt} - install_etc: File = etc_default_aufs + CFLAGS += -I./libau + CFLAGS += -O -Wall + +@@ -28,13 +33,10 @@ LibUtilObj = proc_mnt.o br.o plink.o mta + LibUtilHdr = au_util.h + export + +-all: ver_test ${Man} ${Bin} ${Etc} ++all: ${Man} ${Bin} ${Etc} + ${MAKE} -C libau $@ + ln -sf ./libau/libau*.so . + +-ver_test: ver +- ./ver +- + ${Bin}: LDFLAGS += -static -s + ${Bin}: LDLIBS = -L. -lautil + ${BinObj}: %.o: %.c ${LibUtilHdr} ${LibUtil} +@@ -63,7 +65,7 @@ aufs.5: aufs.in.5 c2tmac + }' aufs.in.5 >> $@ + chmod a-w $@ + +-.INTERMEDIATE: c2sh c2tmac ver ++.INTERMEDIATE: c2sh c2tmac + + Install = install -o root -g root -p + install_sbin: File = mount.aufs umount.aufs auplink +@@ -77,7 +79,7 @@ install_etc: File = etc_default_aufs install_etc: Tgt = ${DESTDIR}/etc/default/aufs install_etc: ${File} install -d $(dir ${Tgt}) -- install -m 644 -o root -g root -p -T ${File} ${Tgt} -+ install -m 644 -p -T ${File} ${Tgt} - - # do not inlcude install_ulib here - install: install_man install_sbin install_ubin install_etc +- ${Install} -m 644 -T ${File} ${Tgt} ++ ${Install} -m 644 ${File} ${Tgt} + install_man: File = aufs.5 + install_man: Tgt = ${DESTDIR}/usr/share/man/man5 + install_man: ${File} diff --git a/package/aufs2-util/src/COPYING b/package/aufs2-util/src/COPYING deleted file mode 100644 index f90922eea..000000000 --- a/package/aufs2-util/src/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/package/aufs2-util/src/Makefile b/package/aufs2-util/src/Makefile deleted file mode 100644 index 544dfc538..000000000 --- a/package/aufs2-util/src/Makefile +++ /dev/null @@ -1,93 +0,0 @@ - -# Copyright (C) 2005-2010 Junjiro R. Okajima -# -# This program, aufs is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -CFLAGS += -I./libau -CFLAGS += -O -Wall - -Cmd = umount.aufs auchk aubrsync -Man = aufs.5 -Etc = etc_default_aufs -Bin = auplink mount.aufs #auctl -BinObj = $(addsuffix .o, ${Bin}) -LibUtil = libautil.a -LibUtilObj = proc_mnt.o br.o plink.o mtab.o -LibUtilHdr = au_util.h -export - -all: ${Man} ${Bin} ${Etc} - ${MAKE} -C libau $@ - ln -sf ./libau/libau*.so . - -${Bin}: LDFLAGS += -static -s -${Bin}: LDLIBS = -L. -lautil -${BinObj}: %.o: %.c ${LibUtilHdr} ${LibUtil} - -${LibUtilObj}: %.o: %.c ${LibUtilHdr} -#${LibUtil}: ${LibUtil}(${LibUtilObj}) -${LibUtil}: $(foreach o, ${LibUtilObj}, ${LibUtil}(${o})) -.NOTPARALLEL: ${LibUtil} - -etc_default_aufs: c2sh aufs.shlib - ${RM} $@ - echo '# aufs variables for shell scripts' > $@ - ./c2sh >> $@ - echo >> $@ - sed -e '0,/^$$/d' aufs.shlib >> $@ - -aufs.5: aufs.in.5 c2tmac - ${RM} $@ - ./c2tmac > $@ - awk '{ \ - gsub(/\140[^\047]*\047/, "\\[oq]&\\[cq]"); \ - gsub(/\\\[oq\]\140/, "\\[oq]"); \ - gsub(/\047\\\[cq\]/, "\\[cq]"); \ - gsub(/\047/, "\\[aq]"); \ - print; \ - }' aufs.in.5 >> $@ - chmod a-w $@ - -.INTERMEDIATE: c2sh c2tmac - -Install = install -o root -g root -p -install_sbin: File = mount.aufs umount.aufs auplink -install_sbin: Tgt = ${DESTDIR}/sbin -install_ubin: File = auchk aubrsync #auctl -install_ubin: Tgt = ${DESTDIR}/usr/bin -install_sbin install_ubin: ${File} - install -d ${Tgt} - ${Install} -m 755 ${File} ${Tgt} -install_etc: File = etc_default_aufs -install_etc: Tgt = ${DESTDIR}/etc/default/aufs -install_etc: ${File} - install -d $(dir ${Tgt}) - ${Install} -m 644 -T ${File} ${Tgt} -install_man: File = aufs.5 -install_man: Tgt = ${DESTDIR}/usr/share/man/man5 -install_man: ${File} - install -d ${Tgt} - ${Install} -m 644 ${File} ${Tgt} -install_ulib: - ${MAKE} -C libau $@ - -install: install_man install_sbin install_ubin install_etc install_ulib - -clean: - ${RM} ${Man} ${Bin} ${Etc} ${LibUtil} libau.so* *~ - ${RM} ${BinObj} ${LibUtilObj} - ${MAKE} -C libau $@ - --include priv.mk diff --git a/package/aufs2-util/src/README b/package/aufs2-util/src/README deleted file mode 100644 index 1e1f45422..000000000 --- a/package/aufs2-util/src/README +++ /dev/null @@ -1,46 +0,0 @@ - -Utilities for aufs2 -http://aufs.sf.net -J. R. Okajima - -These utilities are always necessary for aufs2. -If you forget to install them, your aufs may not work correctly. -And these are not for aufs1 essentially, except aubrsync. See below in -detail. - -Makefile in this tree has some customizable make-variables. -- KDIR - specify your kernel source path if necessary -- DESTDIR - specify your install path if necessary. - some commands have to be installed under /sbin. - -o /sbin/mount.aufs, /sbin/umount.aufs - Helpers for util-linux-ng package. You should NOT invoke them - manually. Just install them by "make install". - -o /sbin/auplink - Handles aufs pseudo-link at remount/unmount time. You can invoke it - manually at anytime. - -o /usr/bin/auchk - Similar to generic fsck. Checks whether a branch is healthy or not - from aufs's point of view. - -o /usr/bin/aubrsync - Move files from the upper writable branch to the lower branch. - If you use this script with aufs1, then you need to install aufs.shlib - to /usr/lib/aufs.shlib. Currently only the 20080211 version is tested - for aufs1. - The development of this script is sponcered by ASUSTek Computer Inc. - (http://www.asus.com/). - Kindly they agreed that I keep my aufs work as free software as it has - been. - -o /etc/default/aufs - A library for shell scripts. - - -# Local variables: ; -# mode: text; -# End: ; diff --git a/package/aufs2-util/src/au_util.h b/package/aufs2-util/src/au_util.h deleted file mode 100644 index 21b965510..000000000 --- a/package/aufs2-util/src/au_util.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2005-2009 Junjiro Okajima - * - * This program, aufs is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __AUFS_UTIL_H__ -#define __AUFS_UTIL_H__ - -#include <errno.h> -#include <error.h> - -/* - * error_at_line() is decleared with (__printf__, 5, 6) attribute, - * and our compiler produces a warning unless args is not given. - * __VA_ARGS__ does not help the attribute. - */ -#define AuFin(fmt, args...) \ - error_at_line(errno, errno, __FILE__, __LINE__, fmt, ##args) - -#ifdef DEBUG -#define MTab "/tmp/mtab" -#else -#define MTab "/etc/mtab" -#endif - -/* proc_mounts.c */ -struct mntent; -int au_proc_getmntent(char *mntpnt, struct mntent *rent); - -/* br.c */ -int au_br(char ***br, int *nbr, struct mntent *ent); - -/* plink.c */ -enum { - AuPlink_FLUSH, - AuPlink_CPUP, - AuPlink_LIST -}; -int au_plink(char cwd[], int cmd, int begin_maint, int end_maint); -void au_plink_maint(char *path); - -/* mtab.c */ -void au_print_ent(struct mntent *ent); -int au_update_mtab(char *mntpnt, int do_remount, int do_verbose); - -#define _Dpri(fmt, ...) printf("%s:%d:" fmt, \ - __func__, __LINE__, ##__VA_ARGS__) -#ifdef DEBUG -#define Dpri(fmt, ...) _Dpri(fmt, ##__VA_ARGS__) -#else -#define Dpri(fmt, ...) do { } while(0) -#endif - -#endif /* __AUFS_UTIL_H__ */ diff --git a/package/aufs2-util/src/aubrsync b/package/aufs2-util/src/aubrsync deleted file mode 100755 index 54adac9cb..000000000 --- a/package/aufs2-util/src/aubrsync +++ /dev/null @@ -1,304 +0,0 @@ -#!/bin/sh - -# Copyright (C) 2005-2009 Junjiro Okajima -# -# This program, aufs is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -# -# The development of this script is sponcered by ASUSTek Computer Inc. -# Kindly they agreed that I keep my aufs work as free software as it has -# been. -# - -set -eu -#set -x - -me=$(basename $0) -EEcho() # str -{ - echo ${me}: $@ 1>&2 -} - -f=/sbin/mount.aufs -test ! -x $f && EEcho $f is not installed && exit 1 - -# special handling for backward compatibility. -# -# aufs in the donated eeepc is aufs1 20080211 without CONFIG_AUFS_COMPAT. -# /etc/default/aufs was introduced in aufs1 20080922. -# shwh/noshwh was introduced in aufs1 20080310 with CONFIG_AUFS_SHWH. -# noshwh became always available regardless CONFIG_AUFS_SHWH in aufs1 20081117. - -noshwh=1 -AUFS_VERSION=20080211 -f=/etc/default/aufs -if [ -s $f ] -then - . $f -else - echo ${me}: warning, broken $f, assuming aufs is $AUFS_VERSION - f=/usr/lib/aufs.shlib - test ! -s $f && EEcho $f is not installed && exit 1 - . $f - - case $AUFS_VERSION in - 200*) # aufs1 - test $AUFS_VERSION -lt 20081117 && noshwh=0 - ;; - esac - AUFS_SUPER_MAGIC=1635083891 - AUFS_SUPER_MAGIC_HEX=0x61756673 - AUFS_WH_PFX=.wh. - AUFS_WH_PFX2=.wh..wh. - AUFS_WH_DIROPQ=.wh..wh..opq -fi - -######################################## - -_Rsync="rsync --exclude=lost+found" -Rsync="$_Rsync -aHSx --devices --specials --delete-before" -Copy="$Rsync" -Move="$Copy" -RsyncWh="$_Rsync -ptgoHx" - -FindForRm() # rw -{ - echo "find \"$1\" -xdev -depth \( - \( ! -type d - \( -name $AUFS_WH_DIROPQ - -o ! -name ${AUFS_WH_PFX2}\* \) \) - -o \( -type d - ! -name ${AUFS_WH_PFX2}\* - ! -wholename \"$1\" - ! -wholename \"$1/lost+found\" \) - \) -print0" -} - -MoveWh() # rw ro+wh -{ - cd "$1" - find . -xdev -name ${AUFS_WH_PFX}\* ! -name ${AUFS_WH_PFX2}\* \ - -printf '%P\n' | - while read wh - do - f=$(echo "$wh" | sed -e ' - s/^'${AUFS_WH_PFX}'// - t - s:/'${AUFS_WH_PFX}':/: - ') - test -e "$dst/$f" || echo "$wh" - done | - # -v - $RsyncWh --files-from=- ./ "$2" - cd "$OLDPWD" -} - -copy() -{ - $Copy $@ "$mntpnt"/ "$dst" -} - -_move() -{ - set +x - test $hinotify -ne 1 && echo ${me}: warning, -i is not specified - src_is_nfs=0 - test $(stat -f -c %T "$src") = nfs && src_is_nfs=1 - set $quiet - - $Move $@ && - eval $(FindForRm "$src") | - { - if [ $src_is_nfs -eq 1 ] - then - mount -o remount "$mntpnt" - mount -o remount "$src" - fi - xargs -r0 rm -fr #-v - } -} - -move() -{ - _move $@ "$mntpnt"/ "$dst" -} - -move_with_wh() -{ - { - set +x - MoveWh "$src" "$dst" - set $quiet - } && - move --exclude=${AUFS_WH_PFX}\* -} - -# backward compatibility -move_w() -{ - move_with_wh $@ -} - -Usage() -{ - t=$(FindForRm src_branch | sed -e ' - s/"//g - $b - s/$/ \\/') - - cat <<- EOF - $me Options move | move_with_wh | copy \\ - mntpnt src_branch dst_branch [ options for rsync ] - - generic form: - $me [ -w | --wh ] [ -i | --inotify ] Options \\ - mntpnt cmd [ parameters for cmd ] - - Options: - [ -n | --dry_run ] - [ -q | --quiet ] - - The dst_branch must be mounted as writable. - During the operation, the mntpnt is set readonly. - If you are opening a file for writing on the writable branch, - you need to close the file before invoking this script. - The -w or --wh option requires CONFIG_AUFS_SHWH enabled. - The -i or --inotify option requires CONFIG_AUFS_HINOTIFY enabled. - - 'copy' is a shortcut for - $me mntpnt \\ - $Copy mntpnt/ dst_branch - 'move' is a shortcut for - $me mntpnt \\ - "$Move \\ - mntpnt/ dst_branch && \\ - $t |\\ - xargs -r0 rm -fr" - Note: in most cases, you will need '-i' option, and - find(1) is invoked by $me only when rsync(1) - succeded. - 'move_with_wh' is a simple variation of 'move' which moves - whiteouts separately before the actual 'move'. - - If you execute this script under linux-2.6.24 or earlier, the - kernel may produce a harmless warning "inotify.c:NNN - set_dentry_child_flags()". The message was already removed in - linux-2.6.25. - - examples: - - Copy and reflect all the modification (modifed files, newly - created and removed ones) in the upper branch to the lower - branch. This operation is for aufs which has only 2 branches, - and mainly for a system shutdown script. - All files on the upper branch remain. - - $ sudo $me copy /your/aufs /your/upper_branch /your/lower_branch - - - Like above (2 branches), move and reflect all modifications - from upper to lower. Almost all files on the upper branch will - be removed. You can still use this aufs after the - operation. But the inode number may be changed. If your - application which depends upon the inode number was running at - that time, it may not work correctly. - - $ sudo $me move /your/aufs /your/upper_branch /your/lower_branch - EOF - -# - Like above (2 branches), generate a new middle layer like a -# snapshot including whiteouts and make the upper_branch almost -# empty, but untouch the lower_branch. -# -# $ img=/hda1/a.ext2 -# $ dd if=/dev/zero of=\$img bs=4k count=1k -# $ mkfs -t ext2 -F \$img -# $ sudo mount -o rw,loop \$img /your/new_branch -# $ sudo mount -o remount,ins:1:/your/new_branch=ro+wh /your/aufs -# $ sudo $me _move /your/aufs /your/upper_branch /your/lower_branch \\ -# "--remove-source-files \\ -# --exclude=$AUFS_WH_BASE \\ -# --exclude=$AUFS_WH_PLINKDIR \\ -# --exclude=$AUFS_WH_TMPDIR \\ -# /your/upper_branch/ /your/new_branch; \\ -# mount -o remount,ro /your/new_branch" -# EOF -} - -######################################## - -wh=0 -hinotify=0 -quiet=-x -dry_run= -cmd= -cmd_opts= -for i -do - case $i in - -w|--wh) wh=1;; - -i|--inotify) hinotify=1;; - -n|--dry_run) dry_run=echo;; - -q|--quiet) quiet=+x;; - -h|--help) Usage; exit 0;; - --) shift; break;; - *) break;; - esac - shift -done - -test $# -lt 2 && Usage 1>&2 && exit 1 -case "$1" in -_move|move|copy|move_w|move_with_wh) - test $# -lt 4 && Usage 1>&2 && exit 1 - cmd=$1 - SetDir mntpnt "$2" - SetDir src "$3" - SetDir dst "$4" - shift 4 - wh=0 - ;; -*) - SetDir mntpnt "$1" - cmd="$2" - shift 2 - ;; -esac -cmd_opts="$@" - -case $(stat -f -c %T "$mntpnt") in -aufs|UNKNOWN*${AUFS_SUPER_MAGIC_HEX}*) ;; -*) - EEcho "$mntpnt" is not aufs - exit 1 - ;; -esac - -cur_opts=$(MntOpts "$mntpnt") -test ! "$cur_opts" && -EEcho bad /proc/mounts or "$mntpnt" is not mounted && -exit 1 -cur_opts="udba=reval,noshwh,$cur_opts" -test $noshwh -eq 0 && cur_opts=$(echo $cur_opts | sed -e 's/,noshwh//') - -# force flushing the pusedo-links -tmp_opts="remount,ro,udba=reval,noshwh" -test $noshwh -eq 0 && tmp_opts=$(echo $tmp_opts | sed -e 's/,noshwh//') -test $wh -eq 1 && tmp_opts="$tmp_opts,shwh" -test $hinotify -eq 1 && tmp_opts="$tmp_opts,udba=inotify" - -# here we go -trap "$dry_run mount -o remount,$cur_opts \"$mntpnt\"" EXIT -set $quiet -$dry_run mount -o $tmp_opts "$mntpnt" -eval "$dry_run $cmd $cmd_opts" diff --git a/package/aufs2-util/src/auchk b/package/aufs2-util/src/auchk deleted file mode 100755 index 26a3d8027..000000000 --- a/package/aufs2-util/src/auchk +++ /dev/null @@ -1,130 +0,0 @@ -#!/bin/sh - - -# Copyright (C) 2005-2009 Junjiro Okajima -# -# This program, aufs is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -set -eu -#set -x - -EEcho() # str -{ - echo $0: $@ 1>&2 -} - -f=/etc/default/aufs -. $f - -Usage() -{ - echo $0 writable_branch '[...]' -} - -Pass() # title -{ - pass=$(($pass + 1)) - EEcho \[Pass $pass\] $@ -} - -Remove() # file -{ - if [ -d "$1" ] - then - rm -ir "$1" || : - else - rm -v "$1" || : - fi -} - -for i -do - EEcho Checking "$i" for aufs - - cd "$i" - case $(stat -f -c %T .) in - aufs|UNKNOWN*${AUFS_SUPER_MAGIC_HEX}*) - EEcho $i must not be aufs - cd $OLDPWD - continue - ;; - esac - - ######################################## - pass=0 - Pass Illegal whiteout - find . -name '.wh.*' ! -name '.wh..wh.*' -printf '%h\0%f\0' | - xargs -r0n2 | - while read dir wh - do - #echo \""$dir"\" \""$wh"\" - base=$(echo "$wh" | cut -c5-) - test ! -e "$dir/$base" && continue - - ls -ld "$dir/$wh" "$dir/$base" - read -p 'Which to remove [whiteout/real/skip]? ' ans \ - < /dev/tty > /dev/tty 2>&1 - case "$ans" in - [wW]*) Remove "$dir/$wh" || :;; - [rR]*) Remove "$dir/$base" || :;; - *) echo skipped;; - esac - done - - ######################################## - Pass Remained pseudo-links - did=0 - for plink in ${AUFS_WH_PLINKDIR}/* - do - test ! -e "$plink" && break - if [ -d "$plink" ] - then - EEcho illegal "$plink" - continue - fi - - did=1 - #ls -l "$plink" || : - find . -inum $(basename "$plink" | cut -f2 -d .) -ls || : - done - if [ $did -ne 0 ] - then - cat <<- EOF - They will be maintained at remount or umount time, - if you installed aufs helper scripts (See README - in detail). - If "$i" is not a writeble branch of CURRENTLY mounted - aufs, you need to maintain them by yourself. - EOF - fi - - ######################################## - Pass Remained temp files - for tmp in ${AUFS_WH_TMPDIR}/* - do - test ! -e "$tmp" && break - if [ -d "$tmp" ] - then - EEcho illegal "$tmp" - continue - fi - - ls -l "$tmp" || : - rm -i "$tmp" || : - done - - # nothing to do for xinodir - - cd $OLDPWD -done diff --git a/package/aufs2-util/src/aufs.in.5 b/package/aufs2-util/src/aufs.in.5 deleted file mode 100644 index 0cbb14487..000000000 --- a/package/aufs2-util/src/aufs.in.5 +++ /dev/null @@ -1,1684 +0,0 @@ -.\".so aufs.tmac -. -.eo -.de TQ -.br -.ns -.TP \$1 -.. -.de Bu -.IP \(bu 4 -.. -.ec -.\" end of macro definitions -. -.\" ---------------------------------------------------------------------- -.TH aufs 5 \*[AUFS_VERSION] Linux "Linux Aufs User's Manual" -.SH NAME -aufs \- advanced multi layered unification filesystem. version \*[AUFS_VERSION] - -.\" ---------------------------------------------------------------------- -.SH DESCRIPTION -Aufs is a stackable unification filesystem such as Unionfs, which unifies -several directories and provides a merged single directory. -In the early days, aufs was entirely re-designed and re-implemented -Unionfs Version 1.x series. After -many original ideas, approaches and improvements, it -becomes totally different from Unionfs while keeping the basic features. -See Unionfs Version 1.x series for the basic features. -Recently, Unionfs Version 2.x series begin taking some of same -approaches to aufs's. - -.\" ---------------------------------------------------------------------- -.SH MOUNT OPTIONS -At mount-time, the order of interpreting options is, -.RS -.Bu -simple flags, except xino/noxino and udba=inotify -.Bu -branches -.Bu -xino/noxino -.Bu -udba=inotify -.RE - -At remount-time, -the options are interpreted in the given order, -e.g. left to right. -.RS -.Bu -create or remove -whiteout-base(\*[AUFS_WH_BASE]) and -whplink-dir(\*[AUFS_WH_PLINKDIR]) if necessary -.RE -. -.TP -.B br:BRANCH[:BRANCH ...] (dirs=BRANCH[:BRANCH ...]) -Adds new branches. -(cf. Branch Syntax). - -Aufs rejects the branch which is an ancestor or a descendant of another -branch. It is called overlapped. When the branch is loopback-mounted -directory, aufs also checks the source fs-image file of loopback -device. If the source file is a descendant of another branch, it will -be rejected too. - -After mounting aufs or adding a branch, if you move a branch under -another branch and make it descendant of another branch, aufs will not -work correctly. -. -.TP -.B [ add | ins ]:index:BRANCH -Adds a new branch. -The index begins with 0. -Aufs creates -whiteout-base(\*[AUFS_WH_BASE]) and -whplink-dir(\*[AUFS_WH_PLINKDIR]) if necessary. - -If there is the same named file on the lower branch (larger index), -aufs will hide the lower file. -You can only see the highest file. -You will be confused if the added branch has whiteouts (including -diropq), they may or may not hide the lower entries. -.\" It is recommended to make sure that the added branch has no whiteout. - -Even if a process have once mapped a file by mmap(2) with MAP_SHARED -and the same named file exists on the lower branch, -the process still refers the file on the lower(hidden) -branch after adding the branch. -If you want to update the contents of a process address space after -adding, you need to restart your process or open/mmap the file again. -.\" Usually, such files are executables or shared libraries. -(cf. Branch Syntax). -. -.TP -.B del:dir -Removes a branch. -Aufs does not remove -whiteout-base(\*[AUFS_WH_BASE]) and -whplink-dir(\*[AUFS_WH_PLINKDIR]) automatically. -For example, when you add a RO branch which was unified as RW, you -will see whiteout-base or whplink-dir on the added RO branch. - -If a process is referencing the file/directory on the deleting branch -(by open, mmap, current working directory, etc.), aufs will return an -error EBUSY. -. -.TP -.B mod:BRANCH -Modifies the permission flags of the branch. -Aufs creates or removes -whiteout-base(\*[AUFS_WH_BASE]) and/or -whplink-dir(\*[AUFS_WH_PLINKDIR]) if necessary. - -If the branch permission is been changing `rw' to `ro', and a process -is mapping a file by mmap(2) -.\" with MAP_SHARED -on the branch, the process may or may not -be able to modify its mapped memory region after modifying branch -permission flags. -Additioanlly when you enable CONFIG_IMA (in linux-2.6.30 and later), IMA -may produce some wrong messages. But this is equivalent when the -filesystem is changed `ro' in emergency. -(cf. Branch Syntax). -. -.TP -.B append:BRANCH -equivalent to `add:(last index + 1):BRANCH'. -(cf. Branch Syntax). -. -.TP -.B prepend:BRANCH -equivalent to `add:0:BRANCH.' -(cf. Branch Syntax). -. -.TP -.B xino=filename -Use external inode number bitmap and translation table. -When CONFIG_AUFS_EXPORT is enabled, external inode generation table too. -It is set to -<FirstWritableBranch>/\*[AUFS_XINO_FNAME] by default, or -\*[AUFS_XINO_DEFPATH]. -Comma character in filename is not allowed. - -The files are created per an aufs and per a branch filesystem, and -unlinked. So you -cannot find this file, but it exists and is read/written frequently by -aufs. -(cf. External Inode Number Bitmap, Translation Table and Generation Table). - -If you enable CONFIG_SYSFS, the path of xino files are not shown in -/proc/mounts (and /etc/mtab), instead it is shown in -<sysfs>/fs/aufs/si_<id>/xi_path. -Otherwise, it is shown in /proc/mounts unless it is not the default -path. -. -.TP -.B noxino -Stop using external inode number bitmap and translation table. - -If you use this option, -Some applications will not work correctly. -.\" And pseudo link feature will not work after the inode cache is -.\" shrunk. -(cf. External Inode Number Bitmap, Translation Table and Generation Table). -. -.TP -.B trunc_xib -Truncate the external inode number bitmap file. The truncation is done -automatically when you delete a branch unless you do not specify -`notrunc_xib' option. -(cf. External Inode Number Bitmap, Translation Table and Generation Table). -. -.TP -.B notrunc_xib -Stop truncating the external inode number bitmap file when you delete -a branch. -(cf. External Inode Number Bitmap, Translation Table and Generation Table). -. -.TP -.B create_policy | create=CREATE_POLICY -.TQ -.B copyup_policy | copyup | cpup=COPYUP_POLICY -Policies to select one among multiple writable branches. The default -values are `create=tdp' and `cpup=tdp'. -link(2) and rename(2) systemcalls have an exception. In aufs, they -try keeping their operations in the branch where the source exists. -(cf. Policies to Select One among Multiple Writable Branches). -. -.TP -.B verbose | v -Print some information. -Currently, it is only busy file (or inode) at deleting a branch. -. -.TP -.B noverbose | quiet | q | silent -Disable `verbose' option. -This is default value. -. -.TP -.B sum -df(1)/statfs(2) returns the total number of blocks and inodes of -all branches. -Note that there are cases that systemcalls may return ENOSPC, even if -df(1)/statfs(2) shows that aufs has some free space/inode. -. -.TP -.B nosum -Disable `sum' option. -This is default value. -. -.TP -.B dirwh=N -Watermark to remove a dir actually at rmdir(2) and rename(2). - -If the target dir which is being removed or renamed (destination dir) -has a huge number of whiteouts, i.e. the dir is empty logically but -physically, the cost to remove/rename the single -dir may be very high. -It is -required to unlink all of whiteouts internally before issuing -rmdir/rename to the branch. -To reduce the cost of single systemcall, -aufs renames the target dir to a whiteout-ed temporary name and -invokes a pre-created -kernel thread to remove whiteout-ed children and the target dir. -The rmdir/rename systemcall returns just after kicking the thread. - -When the number of whiteout-ed children is less than the value of -dirwh, aufs remove them in a single systemcall instead of passing -another thread. -This value is ignored when the branch is NFS. -The default value is \*[AUFS_DIRWH_DEF]. -.\" . -.\" .TP -.\" .B rdcache=N -. -.TP -.B rdblk=N -Specifies a size of internal VDIR block which is allocated at a time in -byte. -The VDIR block will be allocated several times when necessary. If your -directory has millions of files, you may want to expand this size. -The default value is defined as \*[AUFS_RDBLK_DEF]. -The size has to be lager than NAME_MAX (usually 255) and kmalloc\-able -(the maximum limit depends on your system. at least 128KB is available -for every system). -Whenever you can reset the value to default by specifying rdblk=def. -(cf. Virtual or Vertical Directory Block). -. -.TP -.B rdhash=N -Specifies a size of internal VDIR hash table which is used to compare -the file names under the same named directory on multiple branches. -The VDIR hash table will be allocated in readdir(3)/getdents(2), -rmdir(2) and rename(2) for the existing target directory. If your -directory has millions of files, you may want to expand this size. -The default value is defined as \*[AUFS_RDHASH_DEF]. -The size has to be lager than zero, and it will be multiplied by 4 or 8 -(for 32\-bit and 64\-bit respectively, currently). The result must be -kmalloc\-able -(the maximum limit depends on your system. at least 128KB is available -for every system). -Whenever you can reset the value to default by specifying rdhash=def. -(cf. Virtual or Vertical Directory Block). -. -.TP -.B plink -.TQ -.B noplink -Specifies to use `pseudo link' feature or not. -The default is `plink' which means use this feature. -(cf. Pseudo Link) -. -.TP -.B clean_plink -Removes all pseudo-links in memory. -In order to make pseudo-link permanent, use -`auplink' utility just before one of these operations, -unmounting aufs, -using `ro' or `noplink' mount option, -deleting a branch from aufs, -adding a branch into aufs, -or changing your writable branch as readonly. -If you installed both of /sbin/mount.aufs and /sbin/umount.aufs, and your -mount(8) and umount(8) support them, -`auplink' utility will be executed automatically and flush pseudo-links. -(cf. Pseudo Link) -. -.TP -.B udba=none | reval | inotify -Specifies the level of UDBA (User's Direct Branch Access) test. -(cf. User's Direct Branch Access and Inotify Limitation). -. -.TP -.B diropq=whiteouted | w | always | a -Specifies whether mkdir(2) and rename(2) dir case make the created directory -`opaque' or not. -In other words, to create `\*[AUFS_WH_DIROPQ]' under the created or renamed -directory, or not to create. -When you specify diropq=w or diropq=whiteouted, aufs will not create -it if the -directory was not whiteouted or opaqued. If the directory was whiteouted -or opaqued, the created or renamed directory will be opaque. -When you specify diropq=a or diropq==always, aufs will always create -it regardless -the directory was whiteouted/opaqued or not. -The default value is diropq=w, it means not to create when it is unnecessary. -If you define CONFIG_AUFS_COMPAT at aufs compiling time, the default will be -diropq=a. -You need to consider this option if you are planning to add a branch later -since `diropq' affects the same named directory on the added branch. -. -.TP -.B warn_perm -.TQ -.B nowarn_perm -Adding a branch, aufs will issue a warning about uid/gid/permission of -the adding branch directory, -when they differ from the existing branch's. This difference may or -may not impose a security risk. -If you are sure that there is no problem and want to stop the warning, -use `nowarn_perm' option. -The default is `warn_perm' (cf. DIAGNOSTICS). -. -.TP -.B shwh -.TQ -.B noshwh -By default (noshwh), aufs doesn't show the whiteouts and -they just hide the same named entries in the lower branches. The -whiteout itself also never be appeared. -If you enable CONFIG_AUFS_SHWH and specify `shwh' option, aufs -will show you the name of whiteouts -with keeping its feature to hide the lowers. -Honestly speaking, I am rather confused with this `visible whiteouts.' -But a user who originally requested this feature wrote a nice how-to -document about this feature. See Tips file in the aufs CVS tree. - -.\" ---------------------------------------------------------------------- -.SH Module Parameters -.TP -.B nwkq=N -The number of kernel thread named \*[AUFS_WKQ_NAME]. - -Those threads stay in the system while the aufs module is loaded, -and handle the special I/O requests from aufs. -The default value is \*[AUFS_NWKQ_DEF]. - -The special I/O requests from aufs include a part of copy-up, lookup, -directory handling, pseudo-link, xino file operations and the -delegated access to branches. -For example, Unix filesystems allow you to rmdir(2) which has no write -permission bit, if its parent directory has write permission bit. In aufs, the -removing directory may or may not have whiteout or `dir opaque' mark as its -child. And aufs needs to unlink(2) them before rmdir(2). -Therefore aufs delegates the actual unlink(2) and rmdir(2) to another kernel -thread which has been created already and has a superuser privilege. - -If you enable CONFIG_SYSFS, you can check this value through -<sysfs>/module/aufs/parameters/nwkq. - -. -.TP -.B brs=1 | 0 -Specifies to use the branch path data file under sysfs or not. - -If the number of your branches is large or their path is long -and you meet the limitation of mount(8) ro /etc/mtab, you need to -enable CONFIG_SYSFS and set aufs module parameter brs=1. - -When this parameter is set as 1, aufs does not show `br:' (or dirs=) -mount option through /proc/mounts (and /etc/mtab). So you can -keep yourself from the page limitation of -mount(8) or /etc/mtab. -Aufs shows branch paths through <sysfs>/fs/aufs/si_XXX/brNNN. -Actually the file under sysfs has also a size limitation, but I don't -think it is harmful. - -There is one more side effect in setting 1 to this parameter. -If you rename your branch, the branch path written in /etc/mtab will be -obsoleted and the future remount will meet some error due to the -unmatched parameters (Remember that mount(8) may take the options from -/etc/mtab and pass them to the systemcall). -If you set 1, /etc/mtab will not hold the branch path and you will not -meet such trouble. On the other hand, the entries for the -branch path under sysfs are generated dynamically. So it must not be obsoleted. -But I don't think users want to rename branches so often. - -If CONFIG_SYSFS is disable, this parameter is always set to 0. -. -.TP -.B sysrq=key -Specifies MagicSysRq key for debugging aufs. -You need to enable both of CONFIG_MAGIC_SYSRQ and CONFIG_AUFS_DEBUG. -Currently this is for developers only. -The default is `a'. -. -.TP -.B debug= 0 | 1 -Specifies disable(0) or enable(1) debug print in aufs. -This parameter can be changed dynamically. -You need to enable CONFIG_AUFS_DEBUG. -Currently this is for developers only. -The default is `0' (disable). - -.\" ---------------------------------------------------------------------- -.SH Entries under Sysfs and Debugfs -See linux/Documentation/ABI/*/{sys,debug}fs-aufs. - -.\" ---------------------------------------------------------------------- -.SH Branch Syntax -.TP -.B dir_path[ =permission [ + attribute ] ] -.TQ -.B permission := rw | ro | rr -.TQ -.B attribute := wh | nolwh -dir_path is a directory path. -The keyword after `dir_path=' is a -permission flags for that branch. -Comma, colon and the permission flags string (including `=')in the path -are not allowed. - -Any filesystem can be a branch, But some are not accepted such like -sysfs, procfs and unionfs. -If you specify such filesystems as an aufs branch, aufs will return an error -saying it is unsupported. - -Cramfs in linux stable release has strange inodes and it makes aufs -confused. For example, -.nf -$ mkdir -p w/d1 w/d2 -$ > w/z1 -$ > w/z2 -$ mkcramfs w cramfs -$ sudo mount -t cramfs -o ro,loop cramfs /mnt -$ find /mnt -ls - 76 1 drwxr-xr-x 1 jro 232 64 Jan 1 1970 /mnt - 1 1 drwxr-xr-x 1 jro 232 0 Jan 1 1970 /mnt/d1 - 1 1 drwxr-xr-x 1 jro 232 0 Jan 1 1970 /mnt/d2 - 1 1 -rw-r--r-- 1 jro 232 0 Jan 1 1970 /mnt/z1 - 1 1 -rw-r--r-- 1 jro 232 0 Jan 1 1970 /mnt/z2 -.fi - -All these two directories and two files have the same inode with one -as their link count. Aufs cannot handle such inode correctly. -Currently, aufs involves a tiny workaround for such inodes. But some -applications may not work correctly since aufs inode number for such -inode will change silently. -If you do not have any empty files, empty directories or special files, -inodes on cramfs will be all fine. - -A branch should not be shared as the writable branch between multiple -aufs. A readonly branch can be shared. - -The maximum number of branches is configurable at compile time (127 by -default). - -When an unknown permission or attribute is given, aufs sets ro to that -branch silently. - -.SS Permission -. -.TP -.B rw -Readable and writable branch. Set as default for the first branch. -If the branch filesystem is mounted as readonly, you cannot set it `rw.' -.\" A filesystem which does not support link(2) and i_op\->setattr(), for -.\" example FAT, will not be used as the writable branch. -. -.TP -.B ro -Readonly branch and it has no whiteouts on it. -Set as default for all branches except the first one. Aufs never issue -both of write operation and lookup operation for whiteout to this branch. -. -.TP -.B rr -Real readonly branch, special case of `ro', for natively readonly -branch. Assuming the branch is natively readonly, aufs can optimize -some internal operation. For example, if you specify `udba=inotify' -option, aufs does not set inotify for the things on rr branch. -Set by default for a branch whose fs-type is either `iso9660', -`cramfs' or `romfs' (and `squashfs' for linux\-2.6.29 and later). - -When your branch exists on slower device and you have some -capacity on your hdd, you may want to try ulobdev tool in ULOOP sample. -It can cache the contents of the real devices on another faster device, -so you will be able to get the better access performance. -The ulobdev tool is for a generic block device, and the ulohttp is for a -filesystem image on http server. -If you want to spin down your hdd to save the -battery life or something, then you may want to use ulobdev to save the -access to the hdd, too. -See $AufsCVS/sample/uloop in detail. - -.SS Attribute -. -.TP -.B wh -Readonly branch and it has/might have whiteouts on it. -Aufs never issue write operation to this branch, but lookup for whiteout. -Use this as `<branch_dir>=ro+wh'. -. -.TP -.B nolwh -Usually, aufs creates a whiteout as a hardlink on a writable -branch. This attributes prohibits aufs to create the hardlinked -whiteout, including the source file of all hardlinked whiteout -(\*[AUFS_WH_BASE].) -If you do not like a hardlink, or your writable branch does not support -link(2), then use this attribute. -But I am afraid a filesystem which does not support link(2) natively -will fail in other place such as copy-up. -Use this as `<branch_dir>=rw+nolwh'. -Also you may want to try `noplink' mount option, while it is not recommended. - -.\" .SS FUSE as a branch -.\" A FUSE branch needs special attention. -.\" The struct fuse_operations has a statfs operation. It is OK, but the -.\" parameter is struct statvfs* instead of struct statfs*. So almost -.\" all user\-space implementation will call statvfs(3)/fstatvfs(3) instead of -.\" statfs(2)/fstatfs(2). -.\" In glibc, [f]statvfs(3) issues [f]statfs(2), open(2)/read(2) for -.\" /proc/mounts, -.\" and stat(2) for the mountpoint. With this situation, a FUSE branch will -.\" cause a deadlock in creating something in aufs. Here is a sample -.\" scenario, -.\" .\" .RS -.\" .\" .IN -10 -.\" .Bu -.\" create/modify a file just under the aufs root dir. -.\" .Bu -.\" aufs acquires a write\-lock for the parent directory, ie. the root dir. -.\" .Bu -.\" A library function or fuse internal may call statfs for a fuse branch. -.\" The create=mfs mode in aufs will surely call statfs for each writable -.\" branches. -.\" .Bu -.\" FUSE in kernel\-space converts and redirects the statfs request to the -.\" user\-space. -.\" .Bu -.\" the user\-space statfs handler will call [f]statvfs(3). -.\" .Bu -.\" the [f]statvfs(3) in glibc will access /proc/mounts and issue -.\" stat(2) for the mountpoint. But those require a read\-lock for the aufs -.\" root directory. -.\" .Bu -.\" Then a deadlock occurs. -.\" .\" .RE 1 -.\" .\" .IN -.\" -.\" In order to avoid this deadlock, I would suggest not to call -.\" [f]statvfs(3) from fuse. Here is a sample code to do this. -.\" .nf -.\" struct statvfs stvfs; -.\" -.\" main() -.\" { -.\" statvfs(..., &stvfs) -.\" or -.\" fstatvfs(..., &stvfs) -.\" stvfs.f_fsid = 0 -.\" } -.\" -.\" statfs_handler(const char *path, struct statvfs *arg) -.\" { -.\" struct statfs stfs -.\" -.\" memcpy(arg, &stvfs, sizeof(stvfs)) -.\" -.\" statfs(..., &stfs) -.\" or -.\" fstatfs(..., &stfs) -.\" -.\" arg->f_bfree = stfs.f_bfree -.\" arg->f_bavail = stfs.f_bavail -.\" arg->f_ffree = stfs.f_ffree -.\" arg->f_favail = /* any value */ -.\" } -.\" .fi - -.\" ---------------------------------------------------------------------- -.SH External Inode Number Bitmap, Translation Table and Generation Table (xino) -Aufs uses one external bitmap file and one external inode number -translation table files per an aufs and per a branch -filesystem by default. -Additionally when CONFIG_AUFS_EXPORT is enabled, one external inode -generation table is added. -The bitmap (and the generation table) is for recycling aufs inode number -and the others -are a table for converting an inode number on a branch to -an aufs inode number. The default path -is `first writable branch'/\*[AUFS_XINO_FNAME]. -If there is no writable branch, the -default path -will be \*[AUFS_XINO_DEFPATH]. -.\" A user who executes mount(8) needs the privilege to create xino -.\" file. - -If you enable CONFIG_SYSFS, the path of xino files are not shown in -/proc/mounts (and /etc/mtab), instead it is shown in -<sysfs>/fs/aufs/si_<id>/xi_path. -Otherwise, it is shown in /proc/mounts unless it is not the default -path. - -Those files are always opened and read/write by aufs frequently. -If your writable branch is on flash memory device, it is recommended -to put xino files on other than flash memory by specifying `xino=' -mount option. - -The -maximum file size of the bitmap is, basically, the amount of the -number of all the files on all branches divided by 8 (the number of -bits in a byte). -For example, on a 4KB page size system, if you have 32,768 (or -2,599,968) files in aufs world, -then the maximum file size of the bitmap is 4KB (or 320KB). - -The -maximum file size of the table will -be `max inode number on the branch x size of an inode number'. -For example in 32bit environment, - -.nf -$ df -i /branch_fs -/dev/hda14 2599968 203127 2396841 8% /branch_fs -.fi - -and /branch_fs is an branch of the aufs. When the inode number is -assigned contiguously (without `hole'), the maximum xino file size for -/branch_fs will be 2,599,968 x 4 bytes = about 10 MB. But it might not be -allocated all of disk blocks. -When the inode number is assigned discontinuously, the maximum size of -xino file will be the largest inode number on a branch x 4 bytes. -Additionally, the file size is limited to LLONG_MAX or the s_maxbytes -in filesystem's superblock (s_maxbytes may be smaller than -LLONG_MAX). So the -support-able largest inode number on a branch is less than -2305843009213693950 (LLONG_MAX/4\-1). -This is the current limitation of aufs. -On 64bit environment, this limitation becomes more strict and the -supported largest inode number is less than LLONG_MAX/8\-1. - -The xino files are always hidden, i.e. removed. So you cannot -do `ls \-l xino_file'. -If you enable CONFIG_DEBUG_FS, you can check these information through -<debugfs>/aufs/<si_id>/{xib,xi[0-9]*,xigen}. xib is for the bitmap file, -xi0 ix for the first branch, and xi1 is for the next. xigen is for the -generation table. -xib and xigen are in the format of, - -.nf -<blocks>x<block size> <file size> -.fi - -Note that a filesystem usually has a -feature called pre-allocation, which means a number of -blocks are allocated automatically, and then deallocated -silently when the filesystem thinks they are unnecessary. -You do not have to be surprised the sudden changes of the number of -blocks, when your filesystem which xino files are placed supports the -pre-allocation feature. - -The rests are hidden xino file information in the format of, - -.nf -<file count>, <blocks>x<block size> <file size> -.fi - -If the file count is larger than 1, it means some of your branches are -on the same filesystem and the xino file is shared by them. -Note that the file size may not be equal to the actual consuming blocks -since xino file is a sparse file, i.e. a hole in a file which does not -consume any disk blocks. - -Once you unmount aufs, the xino files for that aufs are totally gone. -It means that the inode number is not permanent across umount or -shutdown. - -The xino files should be created on the filesystem except NFS. -If your first writable branch is NFS, you will need to specify xino -file path other than NFS. -Also if you are going to remove the branch where xino files exist or -change the branch permission to readonly, you need to use xino option -before del/mod the branch. - -The bitmap file can be truncated. -For example, if you delete a branch which has huge number of files, -many inode numbers will be recycled and the bitmap will be truncated -to smaller size. Aufs does this automatically when a branch is -deleted. -You can truncate it anytime you like if you specify `trunc_xib' mount -option. But when the accessed inode number was not deleted, nothing -will be truncated. -If you do not want to truncate it (it may be slow) when you delete a -branch, specify `notrunc_xib' after `del' mount option. - -If you do not want to use xino, use noxino mount option. Use this -option with care, since the inode number may be changed silently and -unexpectedly anytime. -For example, -rmdir failure, recursive chmod/chown/etc to a large and deep directory -or anything else. -And some applications will not work correctly. -.\" When the inode number has been changed, your system -.\" can be crazy. -If you want to change the xino default path, use xino mount option. - -After you add branches, the persistence of inode number may not be -guaranteed. -At remount time, cached but unused inodes are discarded. -And the newly appeared inode may have different inode number at the -next access time. The inodes in use have the persistent inode number. - -When aufs assigned an inode number to a file, and if you create the -same named file on the upper branch directly, then the next time you -access the file, aufs may assign another inode number to the file even -if you use xino option. -Some applications may treat the file whose inode number has been -changed as totally different file. - -.\" ---------------------------------------------------------------------- -.SH Pseudo Link (hardlink over branches) -Aufs supports `pseudo link' which is a logical hard-link over -branches (cf. ln(1) and link(2)). -In other words, a copied-up file by link(2) and a copied-up file which was -hard-linked on a readonly branch filesystem. - -When you have files named fileA and fileB which are -hardlinked on a readonly branch, if you write something into fileA, -aufs copies-up fileA to a writable branch, and write(2) the originally -requested thing to the copied-up fileA. On the writable branch, -fileA is not hardlinked. -But aufs remembers it was hardlinked, and handles fileB as if it existed -on the writable branch, by referencing fileA's inode on the writable -branch as fileB's inode. - -Once you unmount aufs, the plink info for that aufs kept in memory are totally -gone. -It means that the pseudo-link is not permanent. -If you want to make plink permanent, try `auplink' utility just before -one of these operations, -unmounting your aufs, -using `ro' or `noplink' mount option, -deleting a branch from aufs, -adding a branch into aufs, -or changing your writable branch to readonly. - -This utility will reproduces all real hardlinks on a writable branch by linking -them, and removes pseudo-link info in memory and temporary link on the -writable branch. -Since this utility access your branches directly, you cannot hide them by -`mount \-\-bind /tmp /branch' or something. - -If you are willing to rebuild your aufs with the same branches later, you -should use auplink utility before you umount your aufs. -If you installed both of /sbin/mount.aufs and /sbin/umount.aufs, and your -mount(8) and umount(8) support them, -`auplink' utility will be executed automatically and flush pseudo-links. - -.nf -# auplink /your/aufs/root flush -# umount /your/aufs/root -or -# auplink /your/aufs/root flush -# mount -o remount,mod:/your/writable/branch=ro /your/aufs/root -or -# auplink /your/aufs/root flush -# mount -o remount,noplink /your/aufs/root -or -# auplink /your/aufs/root flush -# mount -o remount,del:/your/aufs/branch /your/aufs/root -or -# auplink /your/aufs/root flush -# mount -o remount,append:/your/aufs/branch /your/aufs/root -.fi - -The plinks are kept both in memory and on disk. When they consumes too much -resources on your system, you can use the `auplink' utility at anytime and -throw away the unnecessary pseudo-links in safe. - -Additionally, the `auplink' utility is very useful for some security reasons. -For example, when you have a directory whose permission flags -are 0700, and a file who is 0644 under the 0700 directory. Usually, -all files under the 0700 directory are private and no one else can see -the file. But when the directory is 0711 and someone else knows the 0644 -filename, he can read the file. - -Basically, aufs pseudo-link feature creates a temporary link under the -directory whose owner is root and the permission flags are 0700. -But when the writable branch is NFS, aufs sets 0711 to the directory. -When the 0644 file is pseudo-linked, the temporary link, of course the -contents of the file is totally equivalent, will be created under the -0711 directory. The filename will be generated by its inode number. -While it is hard to know the generated filename, someone else may try peeping -the temporary pseudo-linked file by his software tool which may try the name -from one to MAX_INT or something. -In this case, the 0644 file will be read unexpectedly. -I am afraid that leaving the temporary pseudo-links can be a security hole. -It makes sense to execute `auplink /your/aufs/root flush' -periodically, when your writable branch is NFS. - -When your writable branch is not NFS, or all users are careful enough to set 0600 -to their private files, you do not have to worry about this issue. - -If you do not want this feature, use `noplink' mount option. - -.SS The behaviours of plink and noplink -This sample shows that the `f_src_linked2' with `noplink' option cannot follow -the link. - -.nf -none on /dev/shm/u type aufs (rw,xino=/dev/shm/rw/.aufs.xino,br:/dev/shm/rw=rw:/dev/shm/ro=ro) -$ ls -li ../r?/f_src_linked* ./f_src_linked* ./copied -ls: ./copied: No such file or directory -15 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked -15 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked2 -22 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ./f_src_linked -22 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ./f_src_linked2 -$ echo abc >> f_src_linked -$ cp f_src_linked copied -$ ls -li ../r?/f_src_linked* ./f_src_linked* ./copied -15 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked -15 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked2 -36 -rw-r--r-- 2 jro jro 6 Dec 22 11:03 ../rw/f_src_linked -53 -rw-r--r-- 1 jro jro 6 Dec 22 11:03 ./copied -22 -rw-r--r-- 2 jro jro 6 Dec 22 11:03 ./f_src_linked -22 -rw-r--r-- 2 jro jro 6 Dec 22 11:03 ./f_src_linked2 -$ cmp copied f_src_linked2 -$ - -none on /dev/shm/u type aufs (rw,xino=/dev/shm/rw/.aufs.xino,noplink,br:/dev/shm/rw=rw:/dev/shm/ro=ro) -$ ls -li ../r?/f_src_linked* ./f_src_linked* ./copied -ls: ./copied: No such file or directory -17 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked -17 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked2 -23 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ./f_src_linked -23 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ./f_src_linked2 -$ echo abc >> f_src_linked -$ cp f_src_linked copied -$ ls -li ../r?/f_src_linked* ./f_src_linked* ./copied -17 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked -17 -rw-r--r-- 2 jro jro 2 Dec 22 11:03 ../ro/f_src_linked2 -36 -rw-r--r-- 1 jro jro 6 Dec 22 11:03 ../rw/f_src_linked -53 -rw-r--r-- 1 jro jro 6 Dec 22 11:03 ./copied -23 -rw-r--r-- 2 jro jro 6 Dec 22 11:03 ./f_src_linked -23 -rw-r--r-- 2 jro jro 6 Dec 22 11:03 ./f_src_linked2 -$ cmp copied f_src_linked2 -cmp: EOF on f_src_linked2 -$ -.fi - -.\" -.\" If you add/del a branch, or link/unlink the pseudo-linked -.\" file on a branch -.\" directly, aufs cannot keep the correct link count, but the status of -.\" `pseudo-linked.' -.\" Those files may or may not keep the file data after you unlink the -.\" file on the branch directly, especially the case of your branch is -.\" NFS. - -If you add a branch which has fileA or fileB, aufs does not follow the -pseudo link. The file on the added branch has no relation to the same -named file(s) on the lower branch(es). -If you use noxino mount option, pseudo link will not work after the -kernel shrinks the inode cache. - -This feature will not work for squashfs before version 3.2 since its -inode is tricky. -When the inode is hardlinked, squashfs inodes has the same inode -number and correct link count, but the inode memory object is -different. Squashfs inodes (before v3.2) are generated for each, even -they are hardlinked. - -.\" ---------------------------------------------------------------------- -.SH User's Direct Branch Access (UDBA) -UDBA means a modification to a branch filesystem manually or directly, -e.g. bypassing aufs. -While aufs is designed and implemented to be safe after UDBA, -it can make yourself and your aufs confused. And some information like -aufs inode will be incorrect. -For example, if you rename a file on a branch directly, the file on -aufs may -or may not be accessible through both of old and new name. -Because aufs caches various information about the files on -branches. And the cache still remains after UDBA. - -Aufs has a mount option named `udba' which specifies the test level at -access time whether UDBA was happened or not. -. -.TP -.B udba=none -Aufs trusts the dentry and the inode cache on the system, and never -test about UDBA. With this option, aufs runs fastest, but it may show -you incorrect data. -Additionally, if you often modify a branch -directly, aufs will not be able to trace the changes of inodes on the -branch. It can be a cause of wrong behaviour, deadlock or anything else. - -It is recommended to use this option only when you are sure that -nobody access a file on a branch. -It might be difficult for you to achieve real `no UDBA' world when you -cannot stop your users doing `find / \-ls' or something. -If you really want to forbid all of your users to UDBA, here is a trick -for it. -With this trick, users cannot see the -branches directly and aufs runs with no problem, except `auplink' utility. -But if you are not familiar with aufs, this trick may make -yourself confused. - -.nf -# d=/tmp/.aufs.hide -# mkdir $d -# for i in $branches_you_want_to_hide -> do -> mount -n --bind $d $i -> done -.fi - -When you unmount the aufs, delete/modify the branch by remount, or you -want to show the hidden branches again, unmount the bound -/tmp/.aufs.hide. - -.nf -# umount -n $branches_you_want_to_unbound -.fi - -If you use FUSE filesystem as an aufs branch which supports hardlink, -you should not set this option, since FUSE makes inode objects for -each hardlinks (at least in linux\-2.6.23). When your FUSE filesystem -maintains them at link/unlinking, it is equivalent -to `direct branch access' for aufs. - -. -.TP -.B udba=reval -Aufs tests only the existence of the file which existed. If -the existed file was removed on the branch directly, aufs -discard the cache about the file and -re-lookup it. So the data will be updated. -This test is at minimum level to keep the performance and ensure the -existence of a file. -This is default and aufs runs still fast. - -This rule leads to some unexpected situation, but I hope it is -harmless. Those are totally depends upon cache. Here are just a few -examples. -. -.RS -.Bu -If the file is cached as negative or -not-existed, aufs does not test it. And the file is still handled as -negative after a user created the file on a branch directly. If the -file is not cached, aufs will lookup normally and find the file. -. -.Bu -When the file is cached as positive or existed, and a user created the -same named file directly on the upper branch. Aufs detects the cached -inode of the file is still existing and will show you the old (cached) -file which is on the lower branch. -. -.Bu -When the file is cached as positive or existed, and a user renamed the -file by rename(2) directly. Aufs detects the inode of the file is -still existing. You may or may not see both of the old and new files. -Todo: If aufs also tests the name, we can detect this case. -.RE - -If your outer modification (UDBA) is rare and you can ignore the -temporary and minor differences between virtual aufs world and real -branch filesystem, then try this mount option. -. -.TP -.B udba=inotify -Aufs sets `inotify' to all the accessed directories on its branches -and receives the event about the dir and its children. It consumes -resources, cpu and memory. And I am afraid that the performance will be -hurt, but it is most strict test level. -There are some limitations of linux inotify, see also Inotify -Limitation. -So it is recommended to leave udba default option usually, and set it -to inotify by remount when you need it. - -When a user accesses the file which was notified UDBA before, the cached data -about the file will be discarded and aufs re-lookup it. So the data will -be updated. -When an error condition occurs between UDBA and aufs operation, aufs -will return an error, including EIO. -To use this option, you need to enable CONFIG_INOTIFY and -CONFIG_AUFS_UDBA_INOTIFY. - -To rename/rmdir a directory on a branch directory may reveal the same named -directory on the lower branch. Aufs tries re-lookuping the renamed -directory and the revealed directory and assigning different inode -number to them. But the inode number including their children can be a -problem. The inode numbers will be changed silently, and -aufs may produce a warning. If you rename a directory repeatedly and -reveal/hide the lower directory, then aufs may confuse their inode -numbers too. It depends upon the system cache. - -When you make a directory in aufs and mount other filesystem on it, -the directory in aufs cannot be removed expectedly because it is a -mount point. But the same named directory on the writable branch can -be removed, if someone wants. It is just an empty directory, instead -of a mount point. -Aufs cannot stop such direct rmdir, but produces a warning about it. - -If the pseudo-linked file is hardlinked or unlinked on the branch -directly, its inode link count in aufs may be incorrect. It is -recommended to flush the pseudo-links by auplink script. - -.\" ---------------------------------------------------------------------- -.SH Linux Inotify Limitation -Unfortunately, current inotify (linux\-2.6.18) has some limitations, -and aufs must derive it. - -.SS IN_ATTRIB, updating atime -When a file/dir on a branch is accessed directly, the inode atime (access -time, cf. stat(2)) may or may not be updated. In some cases, inotify -does not fire this event. So the aufs inode atime may remain old. - -.SS IN_ATTRIB, updating nlink -When the link count of a file on a branch is incremented by link(2) -directly, -inotify fires IN_CREATE to the parent -directory, but IN_ATTRIB to the file. So the aufs inode nlink may -remain old. - -.SS IN_DELETE, removing file on NFS -When a file on a NFS branch is deleted directly, inotify may or may -not fire -IN_DELETE event. It depends upon the status of dentry -(DCACHE_NFSFS_RENAMED flag). -In this case, the file on aufs seems still exists. Aufs and any user can see -the file. - -.SS IN_IGNORED, deleted rename target -When a file/dir on a branch is unlinked by rename(2) directly, inotify -fires IN_IGNORED which means the inode is deleted. Actually, in some -cases, the inode survives. For example, the rename target is linked or -opened. In this case, inotify watch set by aufs is removed by VFS and -inotify. -And aufs cannot receive the events anymore. So aufs may show you -incorrect data about the file/dir. - -.\" ---------------------------------------------------------------------- -.SH Virtual or Vertical Directory Block (VDIR) -In order to provide the merged view of file listing, aufs builds -internal directory block on memory. For readdir, aufs performs readdir() -internally for each dir on branches, merges their entries with -eliminating the whiteout\-ed ones, and sets it to the opened file (dir) -object. So the file object has its entry list until it is closed. The -entry list will be updated when the file position is zero (by -rewinddir(3)) and becomes obsoleted. - -Some people may call it can be a security hole or invite DoS attack -since the opened and once readdir\-ed dir (file object) holds its entry -list and becomes a pressure for system memory. But I would say it is similar -to files under /proc or /sys. The virtual files in them also holds a -memory page (generally) while they are opened. When an idea to reduce -memory for them is introduced, it will be applied to aufs too. - -The dynamically allocated memory block for the name of entries has a -unit of \*[AUFS_RDBLK_DEF] bytes by default. -During building dir blocks, aufs creates hash list (hashed and divided by -\*[AUFS_RDHASH_DEF] by default) and judging whether -the entry is whiteouted by its upper branch or already listed. - -These values are suitable for normal environments. But you may have -millions of files or very long filenames under a single directory. For -such cases, you may need to customize these values by specifying rdblk= -and rdhash= aufs mount options. - -For instance, there are 97 files under my /bin, and the total name -length is 597 bytes. - -.nf -$ \\ls -1 /bin | wc - 97 97 597 -.fi - -Strictly speaking, 97 end\-of\-line codes are -included. But it is OK since aufs VDIR also stores the name length in 1 -byte. In this case, you do not need to customize the default values. 597 bytes -filenames will be stored in 2 VDIR memory blocks (597 < -\*[AUFS_RDBLK_DEF] x 2). -And 97 filenames are distributed among \*[AUFS_RDHASH_DEF] lists, so one -list will point 4 names in average. To judge the names is whiteouted or -not, the number of comparison will be 4. 2 memory allocations -and 4 comparison costs low (even if the directory is opened for a long -time). So you do not need to customize. - -If your directory has millions of files, the you will need to specify -rdblk= and rdhash=. - -.nf -$ ls -U /mnt/rotating-rust | wc -l -1382438 -.fi - -In this case, assuming the average length of filenames is 6, in order to -get better time performance I would -recommend to set $((128*1024)) or $((64*1024)) for rdblk, and -$((8*1024)) or $((4*1024)) for rdhash. -You can change these values of the active aufs mount by "mount -o -remount". - -This customization is not for -reducing the memory space, but for reducing time for the number of memory -allocation and the name comparison. The larger value is faster, in -general. Of course, you will need system memory. This is a generic -"time\-vs\-space" problem. - -.\" ---------------------------------------------------------------------- -.SH Copy On Write, or aufs internal copyup and copydown -Every stackable filesystem which implements copy\-on\-write supports the -copyup feature. The feature is to copy a file/dir from the lower branch -to the upper internally. When you have one readonly branch and one -upper writable branch, and you append a string to a file which exists on -the readonly branch, then aufs will copy the file from the readonly -branch to the writable branch with its directory hierarchy. It means one -write(2) involves several logical/internal mkdir(2), creat(2), read(2), -write(2) and close(2) systemcalls -before the actual expected write(2) is performed. Sometimes it may take -a long time, particularly when the file is very large. -If CONFIG_AUFS_DEBUG is enabled, aufs produces a message saying `copying -a large file.' - -You may see the message when you change the xino file path or -truncate the xino/xib files. Sometimes those files can be large and may -take a long time to handle them. - -.\" ---------------------------------------------------------------------- -.SH Policies to Select One among Multiple Writable Branches -Aufs has some policies to select one among multiple writable branches -when you are going to write/modify something. There are two kinds of -policies, one is for newly create something and the other is for -internal copy-up. -You can select them by specifying mount option `create=CREATE_POLICY' -or `cpup=COPYUP_POLICY.' -These policies have no meaning when you have only one writable -branch. If there is some meaning, it must hurt the performance. - -.SS Exceptions for Policies -In every cases below, even if the policy says that the branch where a -new file should be created is /rw2, the file will be created on /rw1. -. -.Bu -If there is a readonly branch with `wh' attribute above the -policy-selected branch and the parent dir is marked as opaque, -or the target (creating) file is whiteouted on the ro+wh branch, then -the policy will be ignored and the target file will be created on the -nearest upper writable branch than the ro+wh branch. -.RS -.nf -/aufs = /rw1 + /ro+wh/diropq + /rw2 -/aufs = /rw1 + /ro+wh/wh.tgt + /rw2 -.fi -.RE -. -.Bu -If there is a writable branch above the policy-selected branch and the -parent dir is marked as opaque or the target file is whiteouted on the -branch, then the policy will be ignored and the target file will be -created on the highest one among the upper writable branches who has -diropq or whiteout. In case of whiteout, aufs removes it as usual. -.RS -.nf -/aufs = /rw1/diropq + /rw2 -/aufs = /rw1/wh.tgt + /rw2 -.fi -.RE -. -.Bu -link(2) and rename(2) systemcalls are exceptions in every policy. -They try selecting the branch where the source exists as possible since -copyup a large file will take long time. If it can't be, ie. the -branch where the source exists is readonly, then they will follow the -copyup policy. -. -.Bu -There is an exception for rename(2) when the target exists. -If the rename target exists, aufs compares the index of the branches -where the source and the target are existing and selects the higher -one. If the selected branch is readonly, then aufs follows the copyup -policy. - -.SS Policies for Creating -. -.TP -.B create=tdp | top\-down\-parent -Selects the highest writable branch where the parent dir exists. If -the parent dir does not exist on a writable branch, then the internal -copyup will happen. The policy for this copyup is always `bottom-up.' -This is the default policy. -. -.TP -.B create=rr | round\-robin -Selects a writable branch in round robin. When you have two writable -branches and creates 10 new files, 5 files will be created for each -branch. -mkdir(2) systemcall is an exception. When you create 10 new directories, -all are created on the same branch. -. -.TP -.B create=mfs[:second] | most\-free\-space[:second] -Selects a writable branch which has most free space. In order to keep -the performance, you can specify the duration (`second') which makes -aufs hold the index of last selected writable branch until the -specified seconds expires. The first time you create something in aufs -after the specified seconds expired, aufs checks the amount of free -space of all writable branches by internal statfs call -and the held branch index will be updated. -The default value is \*[AUFS_MFS_SECOND_DEF] seconds. -. -.TP -.B create=mfsrr:low[:second] -Selects a writable branch in most-free-space mode first, and then -round-robin mode. If the selected branch has less free space than the -specified value `low' in bytes, then aufs re-tries in round-robin mode. -.\" `G', `M' and `K' (case insensitive) can be followed after `low.' Or -Try an arithmetic expansion of shell which is defined by POSIX. -For example, $((10 * 1024 * 1024)) for 10M. -You can also specify the duration (`second') which is equivalent to -the `mfs' mode. -. -.TP -.B create=pmfs[:second] -Selects a writable branch where the parent dir exists, such as tdp -mode. When the parent dir exists on multiple writable branches, aufs -selects the one which has most free space, such as mfs mode. - -.SS Policies for Copy-Up -. -.TP -.B cpup=tdp | top\-down\-parent -Equivalent to the same named policy for create. -This is the default policy. -. -.TP -.B cpup=bup | bottom\-up\-parent -Selects the writable branch where the parent dir exists and the branch -is nearest upper one from the copyup-source. -. -.TP -.B cpup=bu | bottom\-up -Selects the nearest upper writable branch from the copyup-source, -regardless the existence of the parent dir. - -.\" ---------------------------------------------------------------------- -.SH Exporting Aufs via NFS -Aufs is supporting NFS-exporting. -Since aufs has no actual block device, you need to add NFS `fsid' option at -exporting. Refer to the manual of NFS about the detail of this option. - -There are some limitations or requirements. -.RS -.Bu -The branch filesystem must support NFS-exporting. -.Bu -NFSv2 is not supported. When you mount the exported aufs from your NFS -client, you will need to some NFS options like v3 or nfsvers=3, -especially if it is nfsroot. -.Bu -If the size of the NFS file handle on your branch filesystem is large, -aufs will -not be able to handle it. The maximum size of NFSv3 file -handle for a filesystem is 64 bytes. Aufs uses 24 bytes for 32bit -system, plus 12 bytes for 64bit system. The rest is a room for a file -handle of a branch filesystem. -.Bu -The External Inode Number Bitmap, Translation Table and Generation Table -(xino) is -required since NFS file -handle is based upon inode number. The mount option `xino' is enabled -by default. -The external inode generation table and its debugfs entry -(<debugfs>/aufs/si_*/xigen) is created when CONFIG_AUFS_EXPORT is -enabled even if you don't export aufs actually. -The size of the external inode generation table grows only, never be -truncated. You might need to pay attention to the free space of the -filesystem where xino files are placed. By default, it is the first -writable branch. -.Bu -The branch filesystems must be accessible, which means `not hidden.' -It means you need to `mount \-\-move' when you use initramfs and -switch_root(8), or chroot(8). -.RE - -.\" ---------------------------------------------------------------------- -.SH Dentry and Inode Caches -If you want to clear caches on your system, there are several tricks -for that. If your system ram is low, -try `find /large/dir \-ls > /dev/null'. -It will read many inodes and dentries and cache them. Then old caches will be -discarded. -But when you have large ram or you do not have such large -directory, it is not effective. - -If you want to discard cache within a certain filesystem, -try `mount \-o remount /your/mntpnt'. Some filesystem may return an error of -EINVAL or something, but VFS discards the unused dentry/inode caches on the -specified filesystem. - -.\" ---------------------------------------------------------------------- -.SH Compatible/Incompatible with Unionfs Version 1.x Series -If you compile aufs with \-DCONFIG_AUFS_COMPAT, dirs= option and =nfsro -branch permission flag are available. They are interpreted as -br: option and =ro flags respectively. - `debug', `delete', `imap' options are ignored silently. When you -compile aufs without \-DCONFIG_AUFS_COMPAT, these three options are -also ignored, but a warning message is issued. - -Ignoring `delete' option, and to keep filesystem consistency, aufs tries -writing something to only one branch in a single systemcall. It means -aufs may copyup even if the copyup-src branch is specified as writable. -For example, you have two writable branches and a large regular file -on the lower writable branch. When you issue rename(2) to the file on aufs, -aufs may copyup it to the upper writable branch. -If this behaviour is not what you want, then you should rename(2) it -on the lower branch directly. - -And there is a simple shell -script `unionctl' under sample subdirectory, which is compatible with -unionctl(8) in -Unionfs Version 1.x series, except \-\-query action. -This script executes mount(8) with `remount' option and uses -add/del/mod aufs mount options. -If you are familiar with Unionfs Version 1.x series and want to use unionctl(8), you can -try this script instead of using mount \-o remount,... directly. -Aufs does not support ioctl(2) interface. -This script is highly depending upon mount(8) in -util\-linux\-2.12p package, and you need to mount /proc to use this script. -If your mount(8) version differs, you can try modifying this -script. It is very easy. -The unionctl script is just for a sample usage of aufs remount -interface. - -Aufs uses the external inode number bitmap and translation table by -default. - -The default branch permission for the first branch is `rw', and the -rest is `ro.' - -The whiteout is for hiding files on lower branches. Also it is applied -to stop readdir going lower branches. -The latter case is called `opaque directory.' Any -whiteout is an empty file, it means whiteout is just an mark. -In the case of hiding lower files, the name of whiteout is -`\*[AUFS_WH_PFX]<filename>.' -And in the case of stopping readdir, the name is -`\*[AUFS_WH_PFX]\*[AUFS_WH_PFX].opq' or -`\*[AUFS_WH_PFX]__dir_opaque.' The name depends upon your compile -configuration -CONFIG_AUFS_COMPAT. -.\" All of newly created or renamed directory will be opaque. -All whiteouts are hardlinked, -including `<writable branch top dir>/\*[AUFS_WH_BASE].' - -The hardlink on an ordinary (disk based) filesystem does not -consume inode resource newly. But in linux tmpfs, the number of free -inodes will be decremented by link(2). It is recommended to specify -nr_inodes option to your tmpfs if you meet ENOSPC. Use this option -after checking by `df \-i.' - -When you rmdir or rename-to the dir who has a number of whiteouts, -aufs rename the dir to the temporary whiteouted-name like -`\*[AUFS_WH_PFX]<dir>.<random hex>.' Then remove it after actual operation. -cf. mount option `dirwh.' - -.\" ---------------------------------------------------------------------- -.SH Incompatible with an Ordinary Filesystem -stat(2) returns the inode info from the first existence inode among -the branches, except the directory link count. -Aufs computes the directory link count larger than the exact value usually, in -order to keep UNIX filesystem semantics, or in order to shut find(1) mouth up. -The size of a directory may be wrong too, but it has to do no harm. -The timestamp of a directory will not be updated when a file is -created or removed under it, and it was done on a lower branch. - -The test for permission bits has two cases. One is for a directory, -and the other is for a non-directory. In the case of a directory, aufs -checks the permission bits of all existing directories. It means you -need the correct privilege for the directories including the lower -branches. -The test for a non-directory is more simple. It checks only the -topmost inode. - -statfs(2) returns the information of the first branch info except -namelen when `nosum' is specified (the default). The namelen is -decreased by the whiteout prefix length. And the block size may differ -from st_blksize which is obtained by stat(2). - -Remember, seekdir(3) and telldir(3) are not defined in POSIX. They may -not work as you expect. Try rewinddir(3) or re-open the dir. - -The whiteout prefix (\*[AUFS_WH_PFX]) is reserved on all branches. Users should -not handle the filename begins with this prefix. -In order to future whiteout, the maximum filename length is limited by -the longest value \- \*[AUFS_WH_PFX_LEN]. It may be a violation of POSIX. - -If you dislike the difference between the aufs entries in /etc/mtab -and /proc/mounts, and if you are using mount(8) in util\-linux package, -then try ./mount.aufs utility. Copy the script to /sbin/mount.aufs. -This simple utility tries updating -/etc/mtab. If you do not care about /etc/mtab, you can ignore this -utility. -Remember this utility is highly depending upon mount(8) in -util\-linux\-2.12p package, and you need to mount /proc. - -Since aufs uses its own inode and dentry, your system may cache huge -number of inodes and dentries. It can be as twice as all of the files -in your union. -It means that unmounting or remounting readonly at shutdown time may -take a long time, since mount(2) in VFS tries freeing all of the cache -on the target filesystem. - -When you open a directory, aufs will open several directories -internally. -It means you may reach the limit of the number of file descriptor. -And when the lower directory cannot be opened, aufs will close all the -opened upper directories and return an error. - -The sub-mount under the branch -of local filesystem -is ignored. -For example, if you have mount another filesystem on -/branch/another/mntpnt, the files under `mntpnt' will be ignored by aufs. -It is recommended to mount the sub-mount under the mounted aufs. -For example, - -.nf -# sudo mount /dev/sdaXX /ro_branch -# d=another/mntpnt -# sudo mount /dev/sdbXX /ro_branch/$d -# mkdir -p /rw_branch/$d -# sudo mount -t aufs -o br:/rw_branch:/ro_branch none /aufs -# sudo mount -t aufs -o br:/rw_branch/${d}:/ro_branch/${d} none /aufs/another/$d -.fi - -There are several characters which are not allowed to use in a branch -directory path and xino filename. See detail in Branch Syntax and Mount -Option. - -The file-lock which means fcntl(2) with F_SETLK, F_SETLKW or F_GETLK, flock(2) -and lockf(3), is applied to virtual aufs file only, not to the file on a -branch. It means you can break the lock by accessing a branch directly. -TODO: check `security' to hook locks, as inotify does. - -The I/O to the named pipe or local socket are not handled by aufs, even -if it exists in aufs. After the reader and the writer established their -connection if the pipe/socket are copied-up, they keep using the old one -instead of the copied-up one. - -The fsync(2) and fdatasync(2) systemcalls return 0 which means success, even -if the given file descriptor is not opened for writing. -I am afraid this behaviour may violate some standards. Checking the -behaviour of fsync(2) on ext2, aufs decided to return success. - -If you want to use disk-quota, you should set it up to your writable -branch since aufs does not have its own block device. - -When your aufs is the root directory of your system, and your system -tells you some of the filesystem were not unmounted cleanly, try these -procedure when you shutdown your system. -.nf -# mount -no remount,ro / -# for i in $writable_branches -# do mount -no remount,ro $i -# done -.fi -If your xino file is on a hard drive, you also need to specify -`noxino' option or `xino=/your/tmpfs/xino' at remounting root -directory. - -To rename(2) directory may return EXDEV even if both of src and tgt -are on the same aufs. When the rename-src dir exists on multiple -branches and the lower dir has child(ren), aufs has to copyup all his -children. It can be recursive copyup. Current aufs does not support -such huge copyup operation at one time in kernel space, instead -produces a warning and returns EXDEV. -Generally, mv(1) detects this error and tries mkdir(2) and -rename(2) or copy/unlink recursively. So the result is harmless. -If your application which issues rename(2) for a directory does not -support EXDEV, it will not work on aufs. -Also this specification is applied to the case when the src directory -exists on the lower readonly branch and it has child(ren). - -If a sudden accident such like a power failure happens during aufs is -performing, and regular fsck for branch filesystems is completed after -the disaster, you need to extra fsck for aufs writable branches. It is -necessary to check whether the whiteout remains incorrectly or not, -eg. the real filename and the whiteout for it under the same parent -directory. If such whiteout remains, aufs cannot handle the file -correctly. -To check the consistency from the aufs' point of view, you can use a -simple shell script called /sbin/auchk. Its purpose is a fsck tool for -aufs, and it checks the illegal whiteout, the remained -pseudo-links and the remained aufs-temp files. If they are found, the -utility reports you and asks whether to delete or not. -It is recommended to execute /sbin/auchk for every writable branch -filesystem before mounting aufs if the system experienced crash. - - -.\" ---------------------------------------------------------------------- -.SH EXAMPLES -The mount options are interpreted from left to right at remount-time. -These examples -shows how the options are handled. (assuming /sbin/mount.aufs was -installed) - -.nf -# mount -v -t aufs br:/day0:/base none /u -none on /u type aufs (rw,xino=/day0/.aufs.xino,br:/day0=rw:/base=ro) -# mount -v -o remount,\\ - prepend:/day1,\\ - xino=/day1/xino,\\ - mod:/day0=ro,\\ - del:/day0 \\ - /u -none on /u type aufs (rw,xino=/day1/xino,br:/day1=rw:/base=ro) -.fi - -.nf -# mount -t aufs br:/rw none /u -# mount -o remount,append:/ro /u -different uid/gid/permission, /ro -# mount -o remount,del:/ro /u -# mount -o remount,nowarn_perm,append:/ro /u -# -(there is no warning) -.fi - -.\" If you want to expand your filesystem size, aufs may help you by -.\" adding an writable branch. Since aufs supports multiple writable -.\" branches, the old writable branch can be being writable, if you want. -.\" In this example, any modifications to the files under /ro branch will -.\" be copied-up to /new, but modifications to the files under /rw branch -.\" will not. -.\" And the next example shows the modifications to the files under /rw branch -.\" will be copied-up to /new/a. -.\" -.\" Todo: test multiple writable branches policy. cpup=nearest, cpup=exist_parent. -.\" -.\" .nf -.\" # mount -v -t aufs br:/rw:/ro none /u -.\" none on /u type aufs (rw,xino=/rw/.aufs.xino,br:/rw=rw:/ro=ro) -.\" # mkfs /new -.\" # mount -v -o remount,add:1:/new=rw /u -.\" none on /u type aufs (rw,xino=/rw/.aufs.xino,br:/rw=rw:/new=rw:/ro=ro) -.\" .fi -.\" -.\" .nf -.\" # mount -v -t aufs br:/rw:/ro none /u -.\" none on /u type aufs (rw,xino=/rw/.aufs.xino,br:/rw=rw:/ro=ro) -.\" # mkfs /new -.\" # mkdir /new/a new/b -.\" # mount -v -o remount,add:1:/new/b=rw,prepend:/new/a,mod:/rw=ro /u -.\" none on /u type aufs (rw,xino=/rw/.aufs.xino,br:/new/a=rw:/rw=ro:/new/b=rw:/ro=ro) -.\" .fi - -When you use aufs as root filesystem, it is recommended to consider to -exclude some directories. For example, /tmp and /var/log are not need -to stack in many cases. They do not usually need to copyup or to whiteout. -Also the swapfile on aufs (a regular file, not a block device) is not -supported. -In order to exclude the specific dir from aufs, try bind mounting. - -And there is a good sample which is for network booted diskless machines. See -sample/ in detail. - -.\" ---------------------------------------------------------------------- -.SH DIAGNOSTICS -When you add a branch to your union, aufs may warn you about the -privilege or security of the branch, which is the permission bits, -owner and group of the top directory of the branch. -For example, when your upper writable branch has a world writable top -directory, -a malicious user can create any files on the writable branch directly, -like copyup and modify manually. I am afraid it can be a security -issue. - -When you mount or remount your union without \-o ro common mount option -and without writable branch, aufs will warn you that the first branch -should be writable. - -.\" It is discouraged to set both of `udba' and `noxino' mount options. In -.\" this case the inode number under aufs will always be changed and may -.\" reach the end of inode number which is a maximum of unsigned long. If -.\" the inode number reaches the end, aufs will return EIO repeatedly. - -When you set udba other than inotify and change something on your -branch filesystem directly, later aufs may detect some mismatches to -its cache. If it is a critical mismatch, aufs returns EIO. - -When an error occurs in aufs, aufs prints the kernel message with -`errno.' The priority of the message (log level) is ERR or WARNING which -depends upon the message itself. -You can convert the `errno' into the error message by perror(3), -strerror(3) or something. -For example, the `errno' in the message `I/O Error, write failed (\-28)' -is 28 which means ENOSPC or `No space left on device.' - -When CONFIG_AUFS_BR_RAMFS is enabled, you can specify ramfs as an aufs -branch. Since ramfs is simple, it does not set the maximum link count -originally. In aufs, it is very dangerous, particularly for -whiteouts. Finally aufs sets the maximum link count for ramfs. The -value is 32000 which is borrowed from ext2. - - -.\" .SH Current Limitation -. -.\" ---------------------------------------------------------------------- -.\" SYNOPSIS -.\" briefly describes the command or function's interface. For commands, this -.\" shows the syntax of the command and its arguments (including options); bold- -.\" face is used for as-is text and italics are used to indicate replaceable -.\" arguments. Brackets ([]) surround optional arguments, vertical bars (|) sep- -.\" arate choices, and ellipses (...) can be repeated. For functions, it shows -.\" any required data declarations or #include directives, followed by the func- -.\" tion declaration. -. -.\" DESCRIPTION -.\" gives an explanation of what the command, function, or format does. Discuss -.\" how it interacts with files and standard input, and what it produces on -.\" standard output or standard error. Omit internals and implementation -.\" details unless they're critical for understanding the interface. Describe -.\" the usual case; for information on options use the OPTIONS section. If -.\" there is some kind of input grammar or complex set of subcommands, consider -.\" describing them in a separate USAGE section (and just place an overview in -.\" the DESCRIPTION section). -. -.\" RETURN VALUE -.\" gives a list of the values the library routine will return to the caller and -.\" the conditions that cause these values to be returned. -. -.\" EXIT STATUS -.\" lists the possible exit status values or a program and the conditions that -.\" cause these values to be returned. -. -.\" USAGE -.\" describes the grammar of any sublanguage this implements. -. -.\" FILES -.\" lists the files the program or function uses, such as configuration files, -.\" startup files, and files the program directly operates on. Give the full -.\" pathname of these files, and use the installation process to modify the -.\" directory part to match user preferences. For many programs, the default -.\" installation location is in /usr/local, so your base manual page should use -.\" /usr/local as the base. -. -.\" ENVIRONMENT -.\" lists all environment variables that affect your program or function and how -.\" they affect it. -. -.\" SECURITY -.\" discusses security issues and implications. Warn about configurations or -.\" environments that should be avoided, commands that may have security impli- -.\" cations, and so on, especially if they aren't obvious. Discussing security -.\" in a separate section isn't necessary; if it's easier to understand, place -.\" security information in the other sections (such as the DESCRIPTION or USAGE -.\" section). However, please include security information somewhere! -. -.\" CONFORMING TO -.\" describes any standards or conventions this implements. -. -.\" NOTES -.\" provides miscellaneous notes. -. -.\" BUGS -.\" lists limitations, known defects or inconveniences, and other questionable -.\" activities. - -.SH COPYRIGHT -Copyright \(co 2005\-2009 Junjiro R. Okajima - -.SH AUTHOR -Junjiro R. Okajima - -.\" SEE ALSO -.\" lists related man pages in alphabetical order, possibly followed by other -.\" related pages or documents. Conventionally this is the last section. diff --git a/package/aufs2-util/src/aufs.shlib b/package/aufs2-util/src/aufs.shlib deleted file mode 100644 index 7aa07665c..000000000 --- a/package/aufs2-util/src/aufs.shlib +++ /dev/null @@ -1,83 +0,0 @@ -# -# Copyright (C) 2005-2009 Junjiro Okajima -# -# This program, aufs is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -# library functions for aufs shell scripts - -# path in canonical representation -SetDir() # var dir -{ - cd "$2" - eval "$1=\"$PWD\"" - cd "$OLDPWD" -} - -# escape the unprintable characters, mainly for grep-ping /proc/mounts -Esc() # [-e] -{ - sed -r -e ' - s/\\/\\134/g - s/$/\\012/ - ' | - tr -d '\n' | - sed -r -e ' - s/ /\\040/g - s/\t/\\011/g - s/\r/\\015/g - s/\\012$// - ' | - { test $# -eq 1 && - test "$1" = "-e" && - sed -r -e 's/\\/\\\\/g' || - cat; } - echo -} - -# find a mount-entry by its mount-point -FindMntEnt() # mntpnt -{ - proc_mounts=/proc/self/mounts - test ! -e $proc_mounts && proc_mounts=/proc/$$/mounts - test ! -e $proc_mounts && proc_mounts=/proc/mounts - fgrep \ $(echo "$1" | Esc)\ aufs\ $proc_mounts | - tail -n 1 -} - -# current mount options -MntOpts() # mntpnt -{ - FindMntEnt "$1" | - cut -f4 -d' ' -} - -######################################## - -AuDebug() # 1 | 0 [sec] -{ - test $1 -eq 0 && set +x - aufs_debug=/sys/module/aufs/parameters/debug - if [ -f $aufs_debug ] - then - echo $1 | sudo dd of=$aufs_debug 2> /dev/null - test $# -eq 2 && sleep $2 - fi - test $1 -eq 1 && set -x - true -} - -# Local variables: ; -# mode: text; -# End: ; diff --git a/package/aufs2-util/src/auplink.c b/package/aufs2-util/src/auplink.c deleted file mode 100644 index 1b48bea51..000000000 --- a/package/aufs2-util/src/auplink.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2005-2009 Junjiro Okajima - * - * This program, aufs is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "au_util.h" - -static void usage(char *me) -{ - fprintf(stderr, - "usage: %s aufs_mount_point list|cpup|flush\n" - "'list' shows the pseudo-linked inode numbers and filenames.\n" - "'cpup' copies-up all pseudo-link to the writeble branch.\n" - "'flush' calls 'cpup', and then 'mount -o remount,clean_plink=inum'\n" - "and remove the whiteouted plink.\n", me); - exit(EINVAL); -} - -int main(int argc, char *argv[]) -{ - int err, cmd; - char *cwd; - - if (argc != 3) - usage(argv[0]); - - if (!strcmp(argv[2], "flush")) - cmd = AuPlink_FLUSH; - else if (!strcmp(argv[2], "list")) - cmd = AuPlink_LIST; - else if (!strcmp(argv[2], "cpup")) - cmd = AuPlink_CPUP; - else { - errno = EINVAL; - AuFin("%s", argv[2]); - cmd = 0; /* never reach here */ - } - - err = chdir(argv[1]); - if (err) - AuFin("chdir"); - cwd = getcwd(NULL, 0); /* glibc */ - if (!cwd) - AuFin("getcwd"); - return au_plink(cwd, cmd, 1, 0); -} diff --git a/package/aufs2-util/src/br.c b/package/aufs2-util/src/br.c deleted file mode 100644 index 6451c120e..000000000 --- a/package/aufs2-util/src/br.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2005-2009 Junjiro Okajima - * - * This program, aufs is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define _GNU_SOURCE /* strndup */ - -#include <sys/stat.h> -#include <sys/types.h> -#include <mntent.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <linux/aufs_type.h> -#include "au_util.h" - -static int by_opts(char ***br, int *nbr, char *bropt) -{ - char *p, **a; - int l; - - /* bropts is placed at the end of mnt_opts */ - errno = EINVAL; - //puts(bropt); - if (strchr(bropt, ',')) - AuFin("%s", bropt); - - l = strlen(bropt); - p = malloc(l + 2); - if (!p) - AuFin("malloc"); - memcpy(p, bropt, l + 1); - bropt = p; - bropt[l + 1] = 0; /* end marker */ - - *nbr = 1; - while (1) { - p = strchr(p + 1, ':'); - if (!p) - break; - *p = 0; - (*nbr)++; - } - - a = malloc(sizeof(a) * (*nbr + 1)); - if (!a) - AuFin("malloc"); - - *br = a; - *a++ = bropt; - p = bropt; - while (*p) { - p += strlen(p) + 1; - *a++ = p; - } - *--a = NULL; - /* don't free bropt */ - - return 0; -} - -#ifdef DEBUG -#define SiPathPrefix "/tmp/aufs/si_" -#define BufSiz 4 -#else -#define SiPathPrefix "/sys/fs/aufs/si_" -#define BufSiz BUFSIZ -#endif - -static int by_sysfs(char ***br, int *nbr, char *siopt) -{ - int err, i, l, sz; - char buf[BufSiz], path[] = SiPathPrefix "1234567890123456/br32767"; - char *p, *end, **a, *q; - FILE *fp; - - errno = EINVAL; - end = strchr(siopt, ','); - if (end) - i = end - siopt; - else - i = strlen(siopt); - - strncpy(path + sizeof(SiPathPrefix) - 1, siopt, i); - p = path + sizeof(SiPathPrefix) - 1 + i; - strcpy(p, "/br"); - p += 3; /* "/br" */ - *nbr = 0; - err = 0; - while (!err) { - sprintf(p, "%d", (*nbr)++); - err = access(path, F_OK); - } - - a = malloc(sizeof(*br) * *nbr); - if (!a) - AuFin("malloc"); - - (*nbr)--; - *br = a; - for (i = 0; i < *nbr; i++) { - sprintf(p, "%d", i); - fp = fopen(path, "r"); - if (!fp) - AuFin("%s", path); - if (fgets(buf, sizeof(buf), fp) != buf) - AuFin("%s", path); - l = strlen(buf); - if (l < 1) - AuFin("internal error, %d", l); - - q = strndup(buf, l - 1); - if (buf[l - 1] != '\n') { - /* a branch path with crazy length */ - /* stat(2) for sysfs is meaningless */ - sz = sizeof(buf); - do { - free(q); - sz <<= 1; - q = malloc(sz); - if (!q) - AuFin("malloc"); - rewind(fp); - if (fgets(q, sz, fp) != q) - AuFin("%s", path); - l = strlen(q); - } while (q[l - 1] != '\n'); - q[l - 1] = 0; - } - - *a++ = q; - /* don't free q */ - fclose(fp); /* ignore */ - } - *a = NULL; - - return 0; -} - -#define BrOpt ",br:" -#define SiOpt "si" -int au_br(char ***br, int *nbr, struct mntent *ent) -{ - char *p; - - *nbr = 0; - p = strstr(ent->mnt_opts, BrOpt); - if (p) - return by_opts(br, nbr, p + sizeof(BrOpt) - 1); - p = hasmntopt(ent, SiOpt); - if (p) - return by_sysfs(br, nbr, p + sizeof(SiOpt)); - - /* broken opts */ - AuFin("internal error, %s", ent->mnt_opts); - return -1; /* never reach here */ -} diff --git a/package/aufs2-util/src/c2sh.c b/package/aufs2-util/src/c2sh.c deleted file mode 100644 index 80ef044a1..000000000 --- a/package/aufs2-util/src/c2sh.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2005-2009 Junjiro Okajima - * - * This program, aufs is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdio.h> -#include <linux/aufs_type.h> - -#define AUFS_WH_PFX2 AUFS_WH_PFX AUFS_WH_PFX - -int -main(int argc, char *argv[]) -{ -#define p(m, v, fmt) printf("%s=" fmt "\n", m, v) -#define pstr(m) p(#m, m, "%s") -#define pint(m) p(#m, m, "%d") - pstr(AUFS_VERSION); - pint(AUFS_SUPER_MAGIC); - printf("AUFS_SUPER_MAGIC_HEX=0x%x\n", AUFS_SUPER_MAGIC); - pstr(AUFS_WH_PFX); - pstr(AUFS_WH_PFX2); - pstr(AUFS_WKQ_NAME); - pstr(AUFS_WH_DIROPQ); - pstr(AUFS_WH_BASE); - pstr(AUFS_WH_PLINKDIR); - pstr(AUFS_WH_ORPHDIR); - //pint(AUFS_BRANCH_MAX); - return 0; -} diff --git a/package/aufs2-util/src/c2tmac.c b/package/aufs2-util/src/c2tmac.c deleted file mode 100644 index 0018763b4..000000000 --- a/package/aufs2-util/src/c2tmac.c +++ /dev/null @@ -1,44 +0,0 @@ - -/* - * Copyright (C) 2005-2009 Junjiro Okajima - * - * This program, aufs is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdio.h> -#include <linux/aufs_type.h> - -int -main(int argc, char *argv[]) -{ -#define p(m, v, fmt) printf(".ds %s " fmt "\n", m, v) -#define pstr(m) p(#m, m, "%s") -#define pint(m) p(#m, m, "%d") - pstr(AUFS_VERSION); - pstr(AUFS_XINO_FNAME); - pstr(AUFS_XINO_DEFPATH); - pint(AUFS_DIRWH_DEF); - pstr(AUFS_WH_PFX); - pint(AUFS_WH_PFX_LEN); - pstr(AUFS_WKQ_NAME); - pint(AUFS_NWKQ_DEF); - pstr(AUFS_WH_DIROPQ); - pstr(AUFS_WH_BASE); - pstr(AUFS_WH_PLINKDIR); - pint(AUFS_MFS_SECOND_DEF); - pint(AUFS_RDBLK_DEF); - pint(AUFS_RDHASH_DEF); - return 0; -} diff --git a/package/aufs2-util/src/compat.h b/package/aufs2-util/src/compat.h deleted file mode 100644 index ddb436e7e..000000000 --- a/package/aufs2-util/src/compat.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2009 Junjiro Okajima - * - * This program, aufs is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __compat_h__ -#define __compat_h__ - -#ifndef AT_SYMLINK_NOFOLLOW -#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */ - -#define __KERNEL__ -#include <unistd.h> -#include <asm/unistd.h> -#define fstatat fstatat64 -int fstatat(int dirfd, const char *path, struct stat *buf, int flags); -_syscall4(int, fstatat64, int, _dirfd, const char *, path, struct stat *, buf, int, flags); -#undef __KERNEL__ -#endif - -#endif /* __compat_h__ */ diff --git a/package/aufs2-util/src/mount.aufs.c b/package/aufs2-util/src/mount.aufs.c deleted file mode 100644 index d801cfd3c..000000000 --- a/package/aufs2-util/src/mount.aufs.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2005-2009 Junjiro Okajima - * - * This program, aufs is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * The main purpose of this script is updating /etc/mtab and calling auplilnk. - * This behaviour is highly depending on mount(8) in util-linux package. - */ - -#define _XOPEN_SOURCE 500 /* getsubopt */ -#define _BSD_SOURCE /* dirfd */ - -#include <sys/types.h> -#include <dirent.h> -#include <mntent.h> -#include <regex.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <wait.h> - -#include <linux/aufs_type.h> -#include "au_util.h" - -enum { Remount, Bind, Fake, Update, Verbose, AuFlush, LastOpt }; -static void test_opts(char opts[], unsigned char flags[]) -{ - int c; - char *p, *o, *val, *pat[] = { - [Remount] = "remount", - [Bind] = "bind", - NULL - }; - - o = strdup(opts); - if (!o) - AuFin("stdup"); - - p = o; - while (*p) { - c = getsubopt(&p, pat, &val); - switch (c) { - case Remount: - flags[Remount] = 1; - break; - case Bind: - flags[Bind] = 1; - break; - } - } - free(o); -} - -static int test_flush(char opts[]) -{ - int err, i; - regex_t preg; - char *p, *o; - const char *pat = "^((add|ins|append|prepend|del)[:=]" - "|(mod|imod)[:=][^,]*=ro" - "|(noplink|ro)$)"; - - - o = strdup(opts); - if (!o) - AuFin("stdup"); - - p = o; - i = 1; - while ((p = strchr(p, ','))) { - i++; - *p++ = 0; - } - - /* todo: try getsubopt(3)? */ - err = regcomp(&preg, pat, REG_EXTENDED | REG_NOSUB); - if (err) - AuFin("regcomp"); - - p = o; - while (i--) { - if (!regexec(&preg, p, 0, NULL, 0)) { - err = 1; - break; - } else - p += strlen(p) + 1; - } - regfree(&preg); - free(o); - - return err; -} - -static void do_mount(char *dev, char *mntpnt, int argc, char *argv[], - unsigned char flags[]) -{ - int i; - const int ac = argc + 6; - char *av[ac], **a; - - /* todo: eliminate the duplicated options */ - a = av; - *a++ = "mount"; - *a++ = "-i"; - if (flags[Fake]) - *a++ = "-f"; - if (!flags[Bind] || !flags[Update]) - *a++ = "-n"; - if (flags[Bind] && flags[Verbose]) - *a++ = "-v"; - *a++ = "-t"; - *a++ = AUFS_NAME; - - for (i = 3; i < argc; i++) - if (strcmp(argv[i], "-v") && strcmp(argv[i], "-n")) - *a++ = argv[i]; - *a++ = dev; - *a++ = mntpnt; - *a++ = NULL; - -#ifdef DEBUG - for (i = 0; av[i] && i < ac; i++) - puts(av[i]); - exit(0); -#endif - execvp("mount", av); - AuFin("mount"); -} - -/* ---------------------------------------------------------------------- */ - -int main(int argc, char *argv[]) -{ - int err, c, status; - pid_t pid; - unsigned char flags[LastOpt]; - struct mntent ent; - char *dev, *mntpnt, *opts, *cwd; - DIR *cur; - - if (argc < 3) { - errno = EINVAL; - AuFin(NULL); - } - - memset(flags, 0, sizeof(flags)); - flags[Update] = 1; - opts = NULL; - - /* mount(8) always passes the arguments in this order */ - dev = argv[1]; - mntpnt = argv[2]; - while ((c = getopt(argc - 2, argv + 2, "fnvo:")) != -1) { - switch (c) { - case 'f': - flags[Fake] = 1; - break; - case 'n': - flags[Update] = 0; - break; - case 'v': - flags[Verbose] = 1; - break; - case 'o': - opts = optarg; - break; - case '?': - case ':': - errno = EINVAL; - AuFin("internal error"); - } - } - - cur = opendir("."); - if (!cur) - AuFin("."); - err = chdir(mntpnt); - if (err) - AuFin("%s", mntpnt); - cwd = getcwd(NULL, 0); /* glibc */ - if (!cwd) - AuFin("getcwd"); - err = fchdir(dirfd(cur)); - if (err) - AuFin("fchdir"); - closedir(cur); /* ignore */ - - if (opts) - test_opts(opts, flags); - - if (!flags[Bind] && flags[Update]) { - err = access(MTab, R_OK | W_OK); - if (err) - AuFin(MTab); - } - - if (flags[Remount]) { - errno = EINVAL; - if (flags[Bind]) - AuFin("both of remount and bind are specified"); - flags[AuFlush] = test_flush(opts); - if (flags[AuFlush] /* && !flags[Fake] */) { - err = au_plink(cwd, AuPlink_FLUSH, 1, 1); - if (err) - AuFin(NULL); - } - } - - pid = fork(); - if (!pid) { - /* actual mount operation */ - do_mount(dev, mntpnt, argc, argv, flags); - return 0; - } else if (pid < 0) - AuFin("fork"); - - err = waitpid(pid, &status, 0); - if (err < 0) - AuFin("child process"); - - err = !WIFEXITED(status); - if (!err) - err = WEXITSTATUS(status); - - if (!err && !flags[Bind]) { - if (flags[Update]) - err = au_update_mtab(cwd, flags[Remount], - flags[Verbose]); - else if (flags[Verbose]) { - /* withoug blocking plink */ - err = au_proc_getmntent(cwd, &ent); - if (!err) - au_print_ent(&ent); - else - AuFin("internal error"); - } - } - - return err; -} diff --git a/package/aufs2-util/src/mtab.c b/package/aufs2-util/src/mtab.c deleted file mode 100644 index 713e9e267..000000000 --- a/package/aufs2-util/src/mtab.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2005-2009 Junjiro Okajima - * - * This program, aufs is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* cf. fstab.c or the locking for /etc/mtab in util-linux */ -/* - * we need to extract a part of util-linux and create a simple and generic - * library for locking /etc/mtab. - */ - -/* #include <linux/proc_fs.h> */ -#define PROC_SUPER_MAGIC 0x9fa0 -#include <sys/stat.h> -#include <sys/statfs.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <mntent.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include "au_util.h" - -void au_print_ent(struct mntent *ent) -{ - printf("%s on %s type %s (%s)\n", - ent->mnt_fsname, ent->mnt_dir, ent->mnt_type, ent->mnt_opts); -} - -/* ---------------------------------------------------------------------- */ - -static void lock_mtab(char *pid_file) -{ - int err, i; - - for (i = 0; i < 5; i++) { - err = link(pid_file, MTab "~"); - if (!err) - break; - sleep(1); - } - if (err) - AuFin(MTab "~"); -} - -static void unlock_mtab(void) -{ - int err; - - err = rename(MTab "~", MTab); - if (err) - AuFin(MTab); -} - -static void append_mtab(FILE *fp, FILE *ofp, struct mntent *ent) -{ - int err; - struct mntent *p; - - while ((p = getmntent(ofp))) { - err = addmntent(fp, p); - if (err) - AuFin("addmntent"); - } - - err = addmntent(fp, ent); - if (err) - AuFin("addmntent"); -} - -/* todo: there are some cases which options are not changed */ -static void update_mtab(FILE *fp, char *mntpnt, int do_remount, int do_verbose) -{ - int err; - long pos; - FILE *ofp; - struct mntent ent, *p; - - /* prohibit updating mount options for this mntpnt */ - au_plink_maint(mntpnt); - err = au_proc_getmntent(mntpnt, &ent); - if (err) - AuFin("no such mount point"); - - ofp = setmntent(MTab, "r"); - if (!ofp) - AuFin(MTab); - - if (do_remount) { - /* find the last one */ - pos = -1; - while ((p = getmntent(ofp))) { - if (!strcmp(p->mnt_dir, mntpnt)) - pos = ftell(ofp); - } - rewind(ofp); - - if (pos > 0) { - while ((p = getmntent(ofp))) { - if (ftell(ofp) == pos) { - /* replace the line */ - p = &ent; - pos = -1; - } - err = addmntent(fp, p); - if (err) - AuFin("addmntent"); - } - if (pos > 0) - AuFin("internal error"); - } else - append_mtab(fp, ofp, &ent); - } else - append_mtab(fp, ofp, &ent); - - endmntent(ofp); /* ignore */ - au_plink_maint(NULL); - if (do_verbose) - au_print_ent(&ent); -} - -/* ---------------------------------------------------------------------- */ - -int au_update_mtab(char *mntpnt, int do_remount, int do_verbose) -{ - int err, fd, status, e2; - pid_t pid; - ino_t ino; - struct stat st; - struct statfs stfs; - struct flock flock = { - .l_type = F_WRLCK, - .l_whence = SEEK_SET, - .l_start = 0, - .l_len = 0 - }; - char pid_file[sizeof(MTab "~.") + 20]; - FILE *fp; - - err = statfs(MTab, &stfs); - if (stfs.f_type == PROC_SUPER_MAGIC) - return 0; - - snprintf(pid_file, sizeof(pid_file), MTab "~.%d", getpid()); - fd = open(pid_file, O_RDWR | O_CREAT | O_EXCL, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd < 0) - AuFin("%s", pid_file); - err = fcntl(fd, F_SETLK, &flock); - if (err) - AuFin("%s", pid_file); - fp = fdopen(fd, "r+"); - if (!fp) - AuFin("%s", pid_file); - - pid = fork(); - if (!pid) { - lock_mtab(pid_file); - update_mtab(fp, mntpnt, do_remount, do_verbose); - unlock_mtab(); - return 0; - } else if (pid < 0) - AuFin("fork"); - - err = fstat(fd, &st); - if (err) - perror(pid_file); - ino = st.st_ino; - - err = waitpid(pid, &status, 0); - if (err < 0) { - perror(pid_file); - goto out; - } - err = !WIFEXITED(status); - if (!err) - err = WEXITSTATUS(status); - - e2 = unlink(pid_file); - if (e2 && errno != ENOENT) - perror(pid_file); - e2 = stat(MTab "~", &st); - if (!e2) { - if (st.st_ino == ino) { - /* - * The inode number is same, - * it means it is we who made the file. - * If someone else removed our file between stat(2) and - * unlink(2), it is a breakage of the rule. - */ - e2 = unlink(MTab "~"); - if (e2) - perror(MTab); - } - } else if (errno != ENOENT) - perror(MTab "~"); - fclose(fp); - - out: - return err; -} diff --git a/package/aufs2-util/src/plink.c b/package/aufs2-util/src/plink.c deleted file mode 100644 index 6ff16c76a..000000000 --- a/package/aufs2-util/src/plink.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (C) 2005-2009 Junjiro Okajima - * - * This program, aufs is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define _FILE_OFFSET_BITS 64 /* ftw.h */ -#define _XOPEN_SOURCE 500 /* ftw.h */ -#define _GNU_SOURCE /* ftw.h */ - -#include <sys/ioctl.h> -#include <sys/resource.h> -#include <sys/time.h> -#include <sys/types.h> -#include <dirent.h> -#include <ftw.h> -#include <mntent.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <linux/aufs_type.h> -#include "au_util.h" - -/* todo: try argz? */ -static struct name_array { - char *o; - int bytes; - - char *cur; - int nname; -} na; - -static struct ino_array { - char *o; - int bytes; - - union { - char *p; - ino_t *cur; - }; - int nino; -} ia; - -static int na_append(char *plink_dir, char *name) -{ - int l, sz; - char *p; - const int cur = na.cur - na.o; - - l = strlen(plink_dir) + strlen(name) + 2; - sz = na.bytes + l; - p = realloc(na.o, sz); - if (!p) - AuFin("realloc"); - - na.o = p; - na.bytes = sz; - na.cur = p + cur; - na.cur += sprintf(na.cur, "%s/%s", plink_dir, name) + 1; - na.nname++; - - return 0; -} - -static int ia_append(ino_t ino) -{ - int sz; - char *p; - const int cur = ia.p - ia.o; - - sz = na.bytes + sizeof(ino_t); - p = realloc(ia.o, sz); - if (!p) - AuFin("realloc"); - - ia.o = p; - ia.bytes = sz; - ia.p = p + cur; - *ia.cur++ = ino; - ia.nino++; - - return 0; -} - -static int build_array(char *plink_dir) -{ - int err; - DIR *dp; - struct dirent *de; - char *p; - ino_t ino; - - err = access(plink_dir, F_OK); - if (err) - return 0; - - err = 0; - dp = opendir(plink_dir); - if (!dp) - AuFin("%s", plink_dir); - while ((de = readdir(dp))) { - if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) - continue; -#if 0 - if (de->d_type == DT_DIR) { - errno = EISDIR; - AuFin(de->d_name); - } -#endif - - err = na_append(plink_dir, de->d_name); - if (err) - break; - - p = strchr(de->d_name, '.'); - if (!p) { - errno = EINVAL; - AuFin("internal error, %s", de->d_name); - } - *p = 0; - errno = 0; - ino = strtoull(de->d_name, NULL, 0); - if (ino == /*ULLONG_MAX*/-1 && errno == ERANGE) - AuFin("internal error, %s", de->d_name); - err = ia_append(ino); - if (err) - break; - } - closedir(dp); - - return err; -} - -static int ia_test(ino_t ino) -{ - int i; - ino_t *p; - - /* todo: hash table */ - ia.p = ia.o; - p = ia.cur; - for (i = 0; i < ia.nino; i++) - if (*p++ == ino) - return 1; - return 0; -} - -/* ---------------------------------------------------------------------- */ - -static int ftw_list(const char *fname, const struct stat *st, int flags, - struct FTW *ftw) -{ - if (!strcmp(fname + ftw->base, AUFS_WH_PLINKDIR)) - return FTW_SKIP_SUBTREE; - if (flags == FTW_D || flags == FTW_DNR) - return FTW_CONTINUE; - - if (ia_test(st->st_ino)) - puts(fname); - - return FTW_CONTINUE; -} - -static int ftw_cpup(const char *fname, const struct stat *st, int flags, - struct FTW *ftw) -{ - int err; - - if (!strcmp(fname + ftw->base, AUFS_WH_PLINKDIR)) - return FTW_SKIP_SUBTREE; - if (flags == FTW_D || flags == FTW_DNR) - return FTW_CONTINUE; - - /* - * do nothing but update something harmless in order to make it copyup - */ - if (ia_test(st->st_ino)) { - Dpri("%s\n", fname); - if (!S_ISLNK(st->st_mode)) - err = chown(fname, -1, -1); - else - err = lchown(fname, -1, -1); - if (err) - AuFin("%s", fname); - } - - return FTW_CONTINUE; -} - -/* ---------------------------------------------------------------------- */ - -static DIR *dp; -void au_plink_maint(char *path) -{ - int err; - - if (path) { - if (dp) { - errno = EINVAL; - AuFin("dp is not NULL"); - } - dp = opendir(path); - if (!dp) - AuFin("%s", path); - - err = ioctl(dirfd(dp), AUFS_CTL_PLINK_MAINT); -#ifndef DEBUG - if (err) - AuFin("AUFS_CTL_PLINK_MAINT"); -#endif - } else { - err = closedir(dp); - if (err) - AuFin("closedir"); - dp = NULL; - } -} - -void au_clean_plink(void) -{ - int err; - - err = ioctl(dirfd(dp), AUFS_CTL_PLINK_CLEAN); -#ifndef DEBUG - if (err) - AuFin("AUFS_CTL_PLINK_CLEAN"); -#endif -} - -static int do_plink(char *cwd, int cmd, int nbr, char *br[]) -{ - int err, i, l; - struct rlimit rlim; - __nftw_func_t func; - char *p; - - err = 0; - switch (cmd) { - case AuPlink_FLUSH: - /*FALLTHROUGH*/ - case AuPlink_CPUP: - func = ftw_cpup; - break; - case AuPlink_LIST: - func = ftw_list; - break; - default: - errno = EINVAL; - AuFin(NULL); - func = NULL; /* never reach here */ - } - - for (i = 0; i < nbr; i++) { - //puts(br[i]); - p = strchr(br[i], '='); - if (strcmp(p + 1, AUFS_BRPERM_RW) - && strcmp(p + 1, AUFS_BRPERM_RWNLWH)) - continue; - - *p = 0; - l = strlen(br[i]); - p = malloc(l + sizeof(AUFS_WH_PLINKDIR) + 2); - if (!p) - AuFin("malloc"); - sprintf(p, "%s/%s", br[i], AUFS_WH_PLINKDIR); - //puts(p); - err = build_array(p); - if (err) - AuFin("build_array"); - free(p); - } - if (!ia.nino) - goto out; - - if (cmd == AuPlink_LIST) { - ia.p = ia.o; - for (i = 0; i < ia.nino; i++) - printf("%llu ", (unsigned long long)*ia.cur++); - putchar('\n'); - } - - err = getrlimit(RLIMIT_NOFILE, &rlim); - if (err) - AuFin("getrlimit"); - nftw(cwd, func, rlim.rlim_cur - 10, - FTW_PHYS | FTW_MOUNT | FTW_ACTIONRETVAL); - /* ignore */ - - if (cmd == AuPlink_FLUSH) { - au_clean_plink(); - - na.cur = na.o; - for (i = 0; i < na.nname; i++) { - Dpri("%s\n", na.cur); - err = unlink(na.cur); - if (err) - AuFin("%s", na.cur); - na.cur += strlen(na.cur) + 1; - } - } - - out: - free(ia.o); - free(na.o); - return err; -} - -int au_plink(char cwd[], int cmd, int begin_maint, int end_maint) -{ - int err, nbr; - struct mntent ent; - char **br; - - if (begin_maint) - au_plink_maint(cwd); - - err = au_proc_getmntent(cwd, &ent); - if (err) - AuFin("no such mount point"); - - if (hasmntopt(&ent, "noplink")) - goto out; /* success */ - -#ifdef DEBUG - //char a[] = "a,b,br:/tmp/br0=rw:/br1=ro"; - char a[] = "a,b,si=1,c"; - ent.mnt_opts = a; -#endif - err = au_br(&br, &nbr, &ent); - //printf("nbr %d\n", nbr); - if (err) - AuFin(NULL); - - err = do_plink(cwd, cmd, nbr, br); - if (err) - AuFin(NULL); - - out: - if (end_maint) - au_plink_maint(NULL); - return err; -} diff --git a/package/aufs2-util/src/proc_mnt.c b/package/aufs2-util/src/proc_mnt.c deleted file mode 100644 index 5230aa259..000000000 --- a/package/aufs2-util/src/proc_mnt.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2005-2009 Junjiro Okajima - * - * This program, aufs is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <sys/types.h> -#include <errno.h> -#include <mntent.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "au_util.h" - -#define ProcMounts "/proc/self/mounts" - -static void copy_ent(struct mntent *dst, struct mntent *src) -{ - free(dst->mnt_opts); - free(dst->mnt_type); - free(dst->mnt_dir); - free(dst->mnt_fsname); - - dst->mnt_dir = NULL; - dst->mnt_type = NULL; - dst->mnt_opts = NULL; - - dst->mnt_fsname = strdup(src->mnt_fsname); - if (dst->mnt_fsname) - dst->mnt_dir = strdup(src->mnt_dir); - if (dst->mnt_dir) - dst->mnt_type = strdup(src->mnt_type); - if (dst->mnt_type) - dst->mnt_opts = strdup(src->mnt_opts); - if (dst->mnt_opts) { - dst->mnt_freq = src->mnt_freq; - dst->mnt_passno = src->mnt_passno; - } else - AuFin("strdup"); - -} - -int au_proc_getmntent(char *mntpnt, struct mntent *rent) -{ - int found; - struct mntent *p; - FILE *fp; - - fp = setmntent(ProcMounts, "r"); - if (!fp) - AuFin(ProcMounts); - - /* find the last one */ - memset(rent, 0, sizeof(*rent)); - found = 0; - while ((p = getmntent(fp))) - if (!strcmp(p->mnt_dir, mntpnt)) { - Dpri("%s, %s, %s, %s, %d, %d\n", - p->mnt_fsname, p->mnt_dir, p->mnt_type, - p->mnt_opts, p->mnt_freq, p->mnt_passno); - copy_ent(rent, p); - found = 1; - } - endmntent(fp); - - if (!found) { - errno = EINVAL; - AuFin("%s", mntpnt); - } - - return 0; -} diff --git a/package/aufs2-util/src/rdu.c b/package/aufs2-util/src/rdu.c deleted file mode 100644 index ac958f084..000000000 --- a/package/aufs2-util/src/rdu.c +++ /dev/null @@ -1,749 +0,0 @@ -/* - * Copyright (C) 2009 Junjiro Okajima - * - * This program, aufs is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define _ATFILE_SOURCE -#define _GNU_SOURCE -#define _REENTRANT - -#include <linux/aufs_type.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/vfs.h> /* or <sys/statfs.h> */ -#include <assert.h> -#include <dirent.h> -#include <dlfcn.h> -#include <errno.h> -#include <fcntl.h> -#include <pthread.h> -#include <search.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "compat.h" - -/* ---------------------------------------------------------------------- */ - -struct rdu { -#ifdef AuRDU_REENTRANT - pthread_rwlock_t lock; -#else - struct dirent de; -#endif - - int fd; - - unsigned long npos, idx; - struct au_rdu_ent **pos; - - unsigned long nent, sz; - struct au_rdu_ent *ent; - - int shwh; - struct au_rdu_ent *real, *wh; -}; - -static struct rdu **rdu; -#define RDU_STEP 8 -static int rdu_cur, rdu_lim = RDU_STEP; - -/* ---------------------------------------------------------------------- */ - -/* #define RduLocalTest */ -#ifdef RduLocalTest -static int rdu_test_data(struct rdu *p, int err) -{ - struct au_rdu_ent *e = p->ent; - static int i; - - if (!i++) { - err = 3; - e->ino = e->type = e->nlen = 1; - strcpy(e->name, "."); - e += au_rdu_len(e->nlen); - e->ino = e->type = e->nlen = 2; - strcpy(e->name, ".."); - e += au_rdu_len(e->nlen); - e->ino = e->type = e->nlen = 3; - strcpy(e->name, "foo"); - } else - err = 0; - - return err; -} -#else -static int rdu_test_data(struct rdu *p, int err) -{ - return err; -} -#endif - -/* #define RduDebug */ -#ifdef RduDebug -#define DPri(fmt, args...) fprintf(stderr, "%s:%d: " fmt, \ - __func__, __LINE__, ##args) -#else -#define DPri(fmt, args...) do {} while (0) -#endif - -/* ---------------------------------------------------------------------- */ - -#ifdef AuRDU_REENTRANT -static void rdu_rwlock_init(struct rdu *p) -{ - pthread_rwlock_init(&p->lock); -} - -static void rdu_read_lock(struct rdu *p) -{ - pthread_rwlock_rdlock(&p->lock); -} - -static void rdu_write_lock(struct rdu *p) -{ - pthread_rwlock_wrlock(&p->lock); -} - -static void rdu_unlock(struct rdu *p) -{ - pthread_rwlock_unlock(&p->lock); -} - -static pthread_mutex_t rdu_lib_mtx = PTHREAD_MUTEX_INITIALIZER; -#define rdu_lib_lock() pthread_mutex_lock(&rdu_lib_mtx) -#define rdu_lib_unlock() pthread_mutex_unlock(&rdu_lib_mtx) -#define rdu_lib_must_lock() assert(pthread_mutex_trylock(&rdu_lib_mtx)) -#else -static void rdu_rwlock_init(struct rdu *p) -{ - /* empty */ -} - -static void rdu_read_lock(struct rdu *p) -{ - /* empty */ -} - -static void rdu_write_lock(struct rdu *p) -{ - /* empty */ -} - -static void rdu_unlock(struct rdu *p) -{ - /* empty */ -} - -#define rdu_lib_lock() do {} while(0) -#define rdu_lib_unlock() do {} while(0) -#define rdu_lib_must_lock() do {} while(0) -#endif - -/* - * initialize this library, particularly global variables. - */ -static int rdu_lib_init(void) -{ - int err; - - err = 0; - if (rdu) - goto out; - - rdu_lib_lock(); - if (!rdu) { - rdu = calloc(rdu_lim, sizeof(*rdu)); - err = !rdu; - } - rdu_lib_unlock(); - - out: - return err; -} - -static int rdu_append(struct rdu *p) -{ - int err, i; - void *t; - - rdu_lib_must_lock(); - - err = 0; - if (rdu_cur < rdu_lim - 1) - rdu[rdu_cur++] = p; - else { - t = realloc(rdu, rdu_lim + RDU_STEP * sizeof(*rdu)); - if (t) { - rdu = t; - rdu_lim += RDU_STEP; - rdu[rdu_cur++] = p; - for (i = 0; i < RDU_STEP - 1; i++) - rdu[rdu_cur + i] = NULL; - } else - err = -1; - } - - return err; -} - -/* ---------------------------------------------------------------------- */ - -static struct rdu *rdu_new(int fd) -{ - struct rdu *p; - int err; - - p = malloc(sizeof(*p)); - if (p) { - rdu_rwlock_init(p); - p->fd = fd; - p->sz = BUFSIZ; - p->ent = malloc(BUFSIZ); - if (p->ent) { - err = rdu_append(p); - if (!err) - goto out; /* success */ - } - } - free(p); - p = NULL; - - out: - return p; -} - -static struct rdu *rdu_buf_lock(int fd) -{ - struct rdu *p; - int i; - - assert(rdu); - assert(fd >= 0); - - p = NULL; - rdu_lib_lock(); - for (i = 0; i < rdu_cur; i++) - if (rdu[i] && rdu[i]->fd == fd) { - p = rdu[i]; - goto out; - } - - for (i = 0; i < rdu_cur; i++) - if (rdu[i] && rdu[i]->fd == -1) { - p = rdu[i]; - p->fd = fd; - goto out; - } - if (!p) - p = rdu_new(fd); - - out: - if (p) - rdu_write_lock(p); - rdu_lib_unlock(); - - return p; -} - -static void rdu_free(int fd) -{ - struct rdu *p; - - p = rdu_buf_lock(fd); - if (p) { - free(p->ent); - free(p->pos); - p->fd = -1; - p->ent = NULL; - p->pos = NULL; - rdu_unlock(p); - } -} - -/* ---------------------------------------------------------------------- */ - -static int rdu_do_store(int dirfd, struct au_rdu_ent *ent, - struct au_rdu_ent **pos, struct rdu *p) -{ - int err; - unsigned char c; - struct stat st; - - c = ent->name[ent->nlen]; - ent->name[ent->nlen] = 0; - DPri("%s\n", ent->name); - err = fstatat(dirfd, ent->name, &st, AT_SYMLINK_NOFOLLOW); - ent->name[ent->nlen] = c; - if (!err) { - ent->ino = st.st_ino; - pos[p->idx++] = ent; - } else { - DPri("err %d\n", err); - if (errno == ENOENT) - err = 0; - } - - return err; -} - -struct rdu_thread_arg { - int pipefd; - struct rdu *p; -}; - -static void *rdu_thread(void *_arg) -{ - int err, pipefd, dirfd; - ssize_t ssz; - struct rdu_thread_arg *arg = _arg; - struct au_rdu_ent *ent, **pos; - struct rdu *p; - - pipefd = arg->pipefd; - p = arg->p; - dirfd = p->fd; - pos = p->pos; - while (1) { - DPri("read\n"); - ssz = read(pipefd, &ent, sizeof(ent)); - DPri("ssz %zd\n", ssz); - if (ssz != sizeof(ent) || !ent) { - //perror("read"); - break; - } - - //DPri("%p\n", ent); - err = rdu_do_store(dirfd, ent, pos, p); - } - - DPri("here\n"); - return NULL; -} - -static int rdu_store(struct rdu *p, struct au_rdu_ent *ent, int pipefd) -{ -#ifdef RduLocalTest - if (ent) - return rdu_do_store(p->fd, ent, p->pos, p); - return 0; -#else - ssize_t ssz; - - //DPri("%p\n", ent); - ssz = write(pipefd, &ent, sizeof(ent)); - DPri("ssz %zd\n", ssz); - //sleep(1); - return ssz != sizeof(ent); -#endif -} - -/* ---------------------------------------------------------------------- */ -/* the heart of this library */ - -static void rdu_tfree(void *node) -{ - /* empty */ -} - -static int rdu_ent_compar(const void *_a, const void *_b) -{ - int ret; - const struct au_rdu_ent *a = _a, *b = _b; - - ret = (int)a->nlen - b->nlen; - if (!ret) - ret = memcmp(a->name, b->name, a->nlen); - return ret; -} - -static int rdu_ent_compar_wh(const void *_a, const void *_b) -{ - int ret; - const struct au_rdu_ent *real = _a, *wh = _b; - - if (real->nlen >= AUFS_WH_PFX_LEN - && !memcmp(real->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { - wh = _a; - real = _b; - } - - ret = (int)wh->nlen - AUFS_WH_PFX_LEN - real->nlen; - if (!ret) - ret = memcmp(wh->name + AUFS_WH_PFX_LEN, real->name, - real->nlen); - return ret; -} - -/* tsearch(3) may not be thread-safe */ -static int rdu_ent_append(struct rdu *p, struct au_rdu_ent *ent, int pipefd) -{ - int err; - struct au_rdu_ent *e; - - err = 0; - e = tfind(ent, (void *)&p->wh, rdu_ent_compar_wh); - if (e) - goto out; - - e = tsearch(ent, (void *)&p->real, rdu_ent_compar); - if (e) - err = rdu_store(p, ent, pipefd); - else - err = -1; - - out: - return err; -} - -static int rdu_ent_append_wh(struct rdu *p, struct au_rdu_ent *ent, int pipefd) -{ - int err; - struct au_rdu_ent *e; - - err = 0; - e = tfind(ent, (void *)&p->wh, rdu_ent_compar); - if (e) - goto out; - - e = tsearch(ent, (void *)&p->wh, rdu_ent_compar); - if (e) { - if (p->shwh) - err = rdu_store(p, ent, pipefd); - } else - err = -1; - - out: - return err; -} - -static int rdu_merge(struct rdu *p) -{ - int err; - unsigned long ul; - pthread_t th; - int fds[2]; - struct rdu_thread_arg arg; - struct au_rdu_ent *ent; - void *t; - - err = -1; - p->pos = malloc(sizeof(*p->pos) * p->npos); - if (!p->pos) - goto out; - - /* pipe(2) may not be scheduled well in linux-2.6.23 and earlier */ - err = pipe(fds); - if (err) - goto out_free; - - arg.pipefd = fds[0]; - arg.p = p; -#ifndef RduLocalTest - err = pthread_create(&th, NULL, rdu_thread, &arg); -#endif - if (err) - goto out_close; - - p->real = NULL; - p->wh = NULL; - ent = p->ent; - for (ul = 0; !err && ul < p->npos; ul++) { - if (ent->nlen <= AUFS_WH_PFX_LEN - || strncmp(ent->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) - err = rdu_ent_append(p, ent, fds[1]); - else - err = rdu_ent_append_wh(p, ent, fds[1]); - ent += au_rdu_len(ent->nlen); - } - rdu_store(p, /*ent*/NULL, fds[1]); /* terminate the thread */ - tdestroy(p->real, rdu_tfree); - tdestroy(p->wh, rdu_tfree); - -#ifndef RduLocalTest - pthread_join(th, NULL); -#endif - p->npos = p->idx; - t = realloc(p->pos, sizeof(*p->pos) * p->npos); - if (t) - p->pos = t; - /* t == NULL is not an error */ - - out_close: - close(fds[1]); - close(fds[0]); - if (!err) - goto out; /* success */ - out_free: - free(p->pos); - p->pos = NULL; - out: - return err; -} - -static int rdu_init(struct rdu *p) -{ - int err; - struct aufs_rdu param; - char *t; - - memset(¶m, 0, sizeof(param)); - param.ent = p->ent; - param.sz = p->sz; - t = getenv("AUFS_RDU_BLK"); - if (t) - param.blk = strtoul(t + sizeof("AUFS_RDU_BLK"), NULL, 0); - - do { - err = ioctl(p->fd, AUFS_CTL_RDU, ¶m); - err = rdu_test_data(p, err); - if (err > 0) { - p->npos += err; - if (!param.full) - continue; - - assert(param.blk); - t = realloc(p->ent, p->sz + param.blk); - if (t) { - param.sz = param.blk; - param.ent = (void *)(t + p->sz); - p->ent = (void *)t; - p->sz += param.blk; - } else - err = -1; - } - } while (err > 0); - p->shwh = param.shwh; - if (!err) - err = rdu_merge(p); - - if (err) { - free(p->ent); - p->ent = NULL; - } - - return err; -} - -static int rdu_pos(struct dirent *de, struct rdu *p, long pos) -{ - int err; - struct au_rdu_ent *ent; - - err = -1; - if (pos <= p->npos) { - ent = p->pos[pos]; - de->d_ino = ent->ino; - de->d_off = pos; - de->d_reclen = sizeof(*ent) + ent->nlen; - de->d_type = ent->type; - memcpy(de->d_name, ent->name, ent->nlen); - de->d_name[ent->nlen] = 0; - err = 0; - } - return err; -} - -/* ---------------------------------------------------------------------- */ - -static struct dirent *(*real_readdir)(DIR *dir); -static int (*real_readdir_r)(DIR *dir, struct dirent *de, struct dirent **rde); -static int (*real_closedir)(DIR *dir); - -static int rdu_dl(void **real, char *sym) -{ - char *p; - - if (*real) - return 0; - - dlerror(); /* clear */ - *real = dlsym(RTLD_NEXT, sym); - p = dlerror(); - if (p) - fprintf(stderr, "%s\n", p); - return !!p; -} - -#define RduDlFunc(sym) \ -static int rdu_dl_##sym(void) \ -{ \ - return rdu_dl((void *)&real_##sym, #sym); \ -} - -RduDlFunc(readdir); -RduDlFunc(closedir); - -#ifdef AuRDU_REENTRANT -RduDlFunc(readdir_r); -#else -#define rdu_dl_readdir_r() 1 -#endif - -/* ---------------------------------------------------------------------- */ - -static int rdu_readdir(DIR *dir, struct dirent *de, struct dirent **rde) -{ - int err, fd; - struct rdu *p; - long pos; - struct statfs stfs; - - if (rde) - *rde = NULL; - - errno = EBADF; - fd = dirfd(dir); - err = fd; - if (fd < 0) - goto out; - - err = fstatfs(fd, &stfs); - if (err) - goto out; - - if ( -#ifdef RduLocalTest - 1 || -#endif - stfs.f_type == AUFS_SUPER_MAGIC) { - err = rdu_lib_init(); - if (err) - goto out; - - p = rdu_buf_lock(fd); - if (!p) - goto out; - - pos = telldir(dir); - if (!pos || !p->npos) { - err = rdu_init(p); - rdu_unlock(p); - } - if (err) - goto out; - - rdu_read_lock(p); - if (!de) - de = &p->de; - err = rdu_pos(de, p, pos); - rdu_unlock(p); - if (!err) { - *rde = de; - seekdir(dir, pos + 1); - } - } else if (!de) { - if (!rdu_dl_readdir()) { - err = 0; - *rde = real_readdir(dir); - if (!*rde) - err = -1; - } - } else { - if (!rdu_dl_readdir_r()) - err = real_readdir_r(dir, de, rde); - } - out: - return err; -} - -struct dirent *readdir(DIR *dir) -{ - struct dirent *de; - int err; - - err = rdu_readdir(dir, NULL, &de); - DPri("err %d\n", err); - return de; -} - -#ifdef AuRDU_REENTRANT -int readdir_r(DIR *dirp, struct dirent *de, struct dirent **rde) -{ - return rdu_readdir(dir, de, rde); -} -#endif - -int closedir(DIR *dir) -{ - int err, fd; - struct statfs stfs; - - errno = EBADF; - fd = dirfd(dir); - if (fd < 0) - goto out; - err = fstatfs(fd, &stfs); - if (err) - goto out; - - if (stfs.f_type == AUFS_SUPER_MAGIC) - rdu_free(fd); - if (!rdu_dl_closedir()) - err = real_closedir(dir); - - out: - return err; -} - -#if 0 -extern DIR *opendir (__const char *__name) __nonnull ((1)); -extern int closedir (DIR *__dirp) __nonnull ((1)); -extern struct dirent *__REDIRECT (readdir, (DIR *__dirp), readdir64) - __nonnull ((1)); -extern struct dirent64 *readdir64 (DIR *__dirp) __nonnull ((1)); -extern int readdir_r (DIR *__restrict __dirp, - struct dirent *__restrict __entry, - struct dirent **__restrict __result) - __nonnull ((1, 2, 3)); -extern int readdir64_r (DIR *__restrict __dirp, - struct dirent64 *__restrict __entry, - struct dirent64 **__restrict __result) - __nonnull ((1, 2, 3)); -extern void rewinddir (DIR *__dirp) __THROW __nonnull ((1)); -extern void seekdir (DIR *__dirp, long int __pos) __THROW __nonnull ((1)); -extern long int telldir (DIR *__dirp) __THROW __nonnull ((1)); -extern int dirfd (DIR *__dirp) __THROW __nonnull ((1)); -extern int scandir (__const char *__restrict __dir, - struct dirent ***__restrict __namelist, - int (*__selector) (__const struct dirent *), - int (*__cmp) (__const void *, __const void *)) - __nonnull ((1, 2)); -extern int scandir64 (__const char *__restrict __dir, - struct dirent64 ***__restrict __namelist, - int (*__selector) (__const struct dirent64 *), - int (*__cmp) (__const void *, __const void *)) - __nonnull ((1, 2)); -extern int alphasort (__const void *__e1, __const void *__e2) - __THROW __attribute_pure__ __nonnull ((1, 2)); -extern int alphasort64 (__const void *__e1, __const void *__e2) - __THROW __attribute_pure__ __nonnull ((1, 2)); -extern int versionsort (__const void *__e1, __const void *__e2) - __THROW __attribute_pure__ __nonnull ((1, 2)); -extern int versionsort64 (__const void *__e1, __const void *__e2) - __THROW __attribute_pure__ __nonnull ((1, 2)); -extern __ssize_t getdirentries (int __fd, char *__restrict __buf, - size_t __nbytes, - __off_t *__restrict __basep) - __THROW __nonnull ((2, 4)); -extern __ssize_t getdirentries64 (int __fd, char *__restrict __buf, - size_t __nbytes, - __off64_t *__restrict __basep) - __THROW __nonnull ((2, 4)); -#endif diff --git a/package/aufs2-util/src/umount.aufs b/package/aufs2-util/src/umount.aufs deleted file mode 100755 index 395689236..000000000 --- a/package/aufs2-util/src/umount.aufs +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - - -# Copyright (C) 2005-2009 Junjiro Okajima -# -# This program, aufs is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -# -# The main purpose of this script is calling auplink. -# - -PATH=/usr/bin:/usr/sbin:/bin:/sbin -export PATH - -set -e -#set -x; echo $0 $@ -dev="$1" -shift -auplink "$dev" flush -exec umount -i $@ "$dev" |