From 9c1daa8ad9c98e670bfa76577ae242be16039aa3 Mon Sep 17 00:00:00 2001 From: Enrico Scholz Date: Wed, 2 Mar 2005 00:52:44 +0000 Subject: [PATCH] added *vdlimit functions + tools (patch provided by Daniel Hokka Zakrisson) git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@1874 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- util-vserver/lib/Makefile-files | 86 +++++----- util-vserver/lib/syscall_adddlimit-v13.hc | 34 ++++ util-vserver/lib/syscall_adddlimit.c | 36 ++++ util-vserver/lib/syscall_getdlimit-v13.hc | 46 +++++ util-vserver/lib/syscall_getdlimit.c | 37 ++++ util-vserver/lib/syscall_remdlimit-v13.hc | 34 ++++ util-vserver/lib/syscall_remdlimit.c | 36 ++++ util-vserver/lib/syscall_setdlimit-v13.hc | 40 +++++ util-vserver/lib/syscall_setdlimit.c | 37 ++++ util-vserver/lib/virtual.h | 1 + util-vserver/lib/vserver.h | 36 +++- util-vserver/src/Makefile-files | 8 +- util-vserver/src/vdlimit.c | 275 ++++++++++++++++++++++++++++++ 13 files changed, 663 insertions(+), 43 deletions(-) create mode 100644 util-vserver/lib/syscall_adddlimit-v13.hc create mode 100644 util-vserver/lib/syscall_adddlimit.c create mode 100644 util-vserver/lib/syscall_getdlimit-v13.hc create mode 100644 util-vserver/lib/syscall_getdlimit.c create mode 100644 util-vserver/lib/syscall_remdlimit-v13.hc create mode 100644 util-vserver/lib/syscall_remdlimit.c create mode 100644 util-vserver/lib/syscall_setdlimit-v13.hc create mode 100644 util-vserver/lib/syscall_setdlimit.c create mode 100644 util-vserver/src/vdlimit.c diff --git a/util-vserver/lib/Makefile-files b/util-vserver/lib/Makefile-files index d1a82e3..88f586a 100644 --- a/util-vserver/lib/Makefile-files +++ b/util-vserver/lib/Makefile-files @@ -41,60 +41,68 @@ lib_v13_SRCS = lib/syscall_ctxcreate.c \ lib/syscall_ctxcreate-v13.hc \ lib/syscall_ctxmigrate.c \ lib/syscall_ctxmigrate-v13.hc \ - lib/syscall_enternamespace.c \ - lib/syscall_enternamespace-v13.hc \ - lib/syscall_setnamespace.c \ - lib/syscall_setnamespace-v13.hc \ - lib/syscall_cleanupnamespace.c \ + lib/syscall_adddlimit-v13.hc \ + lib/syscall_adddlimit.c \ lib/syscall_cleanupnamespace-v13.hc \ - lib/syscall_getiattr.c \ + lib/syscall_cleanupnamespace.c \ + lib/syscall_enternamespace-v13.hc \ + lib/syscall_enternamespace.c \ + lib/syscall_getccaps-v13.hc \ + lib/syscall_getccaps.c \ + lib/syscall_getcflags-v13.hc \ + lib/syscall_getcflags.c \ + lib/syscall_getdlimit-v13.hc \ + lib/syscall_getdlimit.c \ lib/syscall_getiattr-fscompat.hc \ lib/syscall_getiattr-v13.hc \ - lib/syscall_setiattr.c \ - lib/syscall_setiattr-fscompat.hc \ - lib/syscall_setiattr-v13.hc \ - lib/syscall_gettasknid.c \ + lib/syscall_getiattr.c \ + lib/syscall_getncaps-net.hc \ + lib/syscall_getncaps.c \ + lib/syscall_getnflags-net.hc \ + lib/syscall_getnflags.c \ + lib/syscall_getnxinfo-net.hc \ + lib/syscall_getnxinfo.c \ lib/syscall_gettasknid-net.hc \ - lib/syscall_gettaskxid.c \ - lib/syscall_gettaskxid-v13.hc \ + lib/syscall_gettasknid.c \ lib/syscall_gettaskxid-oldproc.hc \ - lib/syscall_getnxinfo.c \ - lib/syscall_getnxinfo-net.hc \ - lib/syscall_getvxinfo.c \ - lib/syscall_getvxinfo-v13.hc \ - lib/syscall_getvxinfo-oldproc.hc \ - lib/syscall_getvhiname.c \ - lib/syscall_getvhiname-v13.hc \ + lib/syscall_gettaskxid-v13.hc \ + lib/syscall_gettaskxid.c \ lib/syscall_getvhiname-olduts.hc \ - lib/syscall_setvhiname.c \ - lib/syscall_setvhiname-v13.hc \ - lib/syscall_setvhiname-olduts.hc \ - lib/syscall_getccaps.c \ - lib/syscall_getccaps-v13.hc \ - lib/syscall_getcflags.c \ - lib/syscall_getcflags-v13.hc \ - lib/syscall_getncaps.c \ - lib/syscall_getncaps-net.hc \ - lib/syscall_getnflags.c \ - lib/syscall_getnflags-net.hc \ + lib/syscall_getvhiname-v13.hc \ + lib/syscall_getvhiname.c \ + lib/syscall_getvxinfo-oldproc.hc \ + lib/syscall_getvxinfo-v13.hc \ + lib/syscall_getvxinfo.c \ lib/syscall_netadd-net.hc \ lib/syscall_netadd.c \ - lib/syscall_netremove-net.hc \ - lib/syscall_netremove.c \ - lib/syscall_netcreate.c \ lib/syscall_netcreate-net.hc \ - lib/syscall_netmigrate.c \ + lib/syscall_netcreate.c \ lib/syscall_netmigrate-net.hc \ - lib/syscall_setccaps.c \ + lib/syscall_netmigrate.c \ + lib/syscall_netremove-net.hc \ + lib/syscall_netremove.c \ + lib/syscall_remdlimit-v13.hc \ + lib/syscall_remdlimit.c \ lib/syscall_setccaps-v13.hc \ - lib/syscall_setcflags.c \ + lib/syscall_setccaps.c \ lib/syscall_setcflags-v13.hc \ - lib/syscall_setncaps.c \ + lib/syscall_setcflags.c \ + lib/syscall_setdlimit-v13.hc \ + lib/syscall_setdlimit.c \ + lib/syscall_setiattr-fscompat.hc \ + lib/syscall_setiattr-v13.hc \ + lib/syscall_setiattr.c \ + lib/syscall_setnamespace-v13.hc \ + lib/syscall_setnamespace.c \ lib/syscall_setncaps-net.hc \ - lib/syscall_setnflags.c \ + lib/syscall_setncaps.c \ lib/syscall_setnflags-net.hc \ - lib/syscall_setsched.c \ + lib/syscall_setnflags.c \ lib/syscall_setsched-v13.hc \ + lib/syscall_setsched.c \ + lib/syscall_setvhiname-olduts.hc \ + lib/syscall_setvhiname-v13.hc \ + lib/syscall_setvhiname.c \ lib/bcaps-v13.c \ lib/bcaps_list-v13.c \ lib/ccaps-v13.c \ diff --git a/util-vserver/lib/syscall_adddlimit-v13.hc b/util-vserver/lib/syscall_adddlimit-v13.hc new file mode 100644 index 0000000..18e1a79 --- /dev/null +++ b/util-vserver/lib/syscall_adddlimit-v13.hc @@ -0,0 +1,34 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2005 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" + +static inline ALWAYSINLINE int +vc_add_dlimit_v13(char const *filename, xid_t xid, uint32_t flags) +{ + struct vcmd_ctx_dlimit_base_v0 init; + + memset(&init, 0, sizeof(init)); + init.name = filename; + init.flags = flags; + return vserver(VCMD_add_dlimit, CTX_USER2KERNEL(xid), &init); +} diff --git a/util-vserver/lib/syscall_adddlimit.c b/util-vserver/lib/syscall_adddlimit.c new file mode 100644 index 0000000..b1a7846 --- /dev/null +++ b/util-vserver/lib/syscall_adddlimit.c @@ -0,0 +1,36 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2005 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "linuxvirtual.h" + +#include "vserver-internal.h" + +#ifdef VC_ENABLE_API_V13 +# include "syscall_adddlimit-v13.hc" +#endif + +int +vc_add_dlimit(char const *filename, xid_t xid, uint32_t flags) +{ + CALL_VC(CALL_VC_V13(vc_add_dlimit, filename, xid, flags)); +} diff --git a/util-vserver/lib/syscall_getdlimit-v13.hc b/util-vserver/lib/syscall_getdlimit-v13.hc new file mode 100644 index 0000000..f869e8b --- /dev/null +++ b/util-vserver/lib/syscall_getdlimit-v13.hc @@ -0,0 +1,46 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2005 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" + +static inline ALWAYSINLINE int +vc_get_dlimit_v13(char const *filename, xid_t xid, + uint_least32_t flags, struct vc_ctx_dlimit *limits) +{ + int rc; + struct vcmd_ctx_dlimit_v0 attr = { + .name = filename, + .flags = flags + }; + + rc = vserver(VCMD_get_dlimit, CTX_USER2KERNEL(xid), &attr); + + if (limits) { + limits->space_used = CDLIM_KERNEL2USER(attr.space_used); + limits->space_total = CDLIM_KERNEL2USER(attr.space_total); + limits->inodes_used = CDLIM_KERNEL2USER(attr.inodes_used); + limits->inodes_total = CDLIM_KERNEL2USER(attr.inodes_total); + limits->reserved = CDLIM_KERNEL2USER(attr.reserved); + } + + return rc; +} diff --git a/util-vserver/lib/syscall_getdlimit.c b/util-vserver/lib/syscall_getdlimit.c new file mode 100644 index 0000000..f0e9e8e --- /dev/null +++ b/util-vserver/lib/syscall_getdlimit.c @@ -0,0 +1,37 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2005 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "linuxvirtual.h" + +#include "vserver-internal.h" + +#ifdef VC_ENABLE_API_V13 +# include "syscall_getdlimit-v13.hc" +#endif + +int +vc_get_dlimit(char const *filename, xid_t xid, + uint_least32_t flags, struct vc_ctx_dlimit *limits) +{ + CALL_VC(CALL_VC_V13(vc_get_dlimit, filename, xid, flags, limits)); +} diff --git a/util-vserver/lib/syscall_remdlimit-v13.hc b/util-vserver/lib/syscall_remdlimit-v13.hc new file mode 100644 index 0000000..38df159 --- /dev/null +++ b/util-vserver/lib/syscall_remdlimit-v13.hc @@ -0,0 +1,34 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2005 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" + +static inline ALWAYSINLINE int +vc_rem_dlimit_v13(char const *filename, xid_t xid, uint32_t flags) +{ + struct vcmd_ctx_dlimit_base_v0 init; + + memset(&init, 0, sizeof(init)); + init.name = filename; + init.flags = flags; + return vserver(VCMD_rem_dlimit, CTX_USER2KERNEL(xid), &init); +} diff --git a/util-vserver/lib/syscall_remdlimit.c b/util-vserver/lib/syscall_remdlimit.c new file mode 100644 index 0000000..6c6623d --- /dev/null +++ b/util-vserver/lib/syscall_remdlimit.c @@ -0,0 +1,36 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2005 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "linuxvirtual.h" + +#include "vserver-internal.h" + +#ifdef VC_ENABLE_API_V13 +# include "syscall_remdlimit-v13.hc" +#endif + +int +vc_rem_dlimit(char const *filename, xid_t xid, uint32_t flags) +{ + CALL_VC(CALL_VC_V13(vc_rem_dlimit, filename, xid, flags)); +} diff --git a/util-vserver/lib/syscall_setdlimit-v13.hc b/util-vserver/lib/syscall_setdlimit-v13.hc new file mode 100644 index 0000000..22117a9 --- /dev/null +++ b/util-vserver/lib/syscall_setdlimit-v13.hc @@ -0,0 +1,40 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2005 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" + +static inline ALWAYSINLINE int +vc_set_dlimit_v13(char const *filename, xid_t xid, + uint_least32_t flags, struct vc_ctx_dlimit const *limits) +{ + struct vcmd_ctx_dlimit_v0 attr = { + .name = filename, + .flags = flags, + .space_used = CDLIM_USER2KERNEL(limits->space_used), + .space_total = CDLIM_USER2KERNEL(limits->space_total), + .inodes_used = CDLIM_USER2KERNEL(limits->inodes_used), + .inodes_total = CDLIM_USER2KERNEL(limits->inodes_total), + .reserved = CDLIM_USER2KERNEL(limits->reserved), + }; + + return vserver(VCMD_set_dlimit, CTX_USER2KERNEL(xid), &attr); +} diff --git a/util-vserver/lib/syscall_setdlimit.c b/util-vserver/lib/syscall_setdlimit.c new file mode 100644 index 0000000..84776e6 --- /dev/null +++ b/util-vserver/lib/syscall_setdlimit.c @@ -0,0 +1,37 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2005 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "linuxvirtual.h" + +#include "vserver-internal.h" + +#ifdef VC_ENABLE_API_V13 +# include "syscall_setdlimit-v13.hc" +#endif + +int +vc_set_dlimit(char const *filename, xid_t xid, + uint_least32_t flags, struct vc_ctx_dlimit const *limits) +{ + CALL_VC(CALL_VC_V13(vc_set_dlimit, filename, xid, flags, limits)); +} diff --git a/util-vserver/lib/virtual.h b/util-vserver/lib/virtual.h index 2f5cde4..f880c98 100644 --- a/util-vserver/lib/virtual.h +++ b/util-vserver/lib/virtual.h @@ -26,5 +26,6 @@ #include #include #include +#include #endif // H_UTIL_VSERVER_LIB_VIRTUAL_H diff --git a/util-vserver/lib/vserver.h b/util-vserver/lib/vserver.h index 5bd22a3..276d876 100644 --- a/util-vserver/lib/vserver.h +++ b/util-vserver/lib/vserver.h @@ -72,6 +72,9 @@ #define VC_LIM_INFINITY (~0ULL) #define VC_LIM_KEEP (~1ULL) +#define VC_CDLIM_UNSET (0U) +#define VC_CDLIM_INFINITY (~0U) +#define VC_CDLIM_KEEP (~1U) #ifndef S_CTX_INFO_LOCK # define S_CTX_INFO_LOCK 1 @@ -657,8 +660,34 @@ extern "C" { }; int vc_set_sched(xid_t xid, struct vc_set_sched const *); + + + struct vc_ctx_dlimit { + uint_least32_t space_used; + uint_least32_t space_total; + uint_least32_t inodes_used; + uint_least32_t inodes_total; + uint_least32_t reserved; + }; + + /** Add a disk limit to a file system. */ + int vc_add_dlimit(char const *filename, xid_t xid, + uint_least32_t flags); + /** Remove a disk limit from a file system. */ + int vc_rem_dlimit(char const *filename, xid_t xid, + uint_least32_t flags); + + /** Set a disk limit. */ + int vc_set_dlimit(char const *filename, xid_t xid, + uint_least32_t flags, + struct vc_ctx_dlimit const *limits); + /** Get a disk limit. */ + int vc_get_dlimit(char const *filename, xid_t xid, + uint_least32_t flags, + struct vc_ctx_dlimit *limits); + typedef enum { vcFEATURE_VKILL, vcFEATURE_IATTR, vcFEATURE_RLIMIT, vcFEATURE_COMPAT, vcFEATURE_MIGRATE, vcFEATURE_NAMESPACE, vcFEATURE_SCHED, vcFEATURE_VINFO, vcFEATURE_VHI, @@ -718,15 +747,16 @@ extern "C" { freed by the caller. */ char * vc_getVserverByCtx(xid_t ctx, /*@null@*/vcCfgStyle *style, /*@null@*/char const *revdir); - + #define vcSKEL_INTERFACES 1u #define vcSKEL_PKGMGMT 2u #define vcSKEL_FILESYSTEM 4u - + /** Create a basic configuration skeleton for a vserver plus toplevel * directories for pkgmanagemt and filesystem (when requested). */ int vc_createSkeleton(char const *id, vcCfgStyle style, int flags); - + + #ifdef __cplusplus } #endif diff --git a/util-vserver/src/Makefile-files b/util-vserver/src/Makefile-files index 1a976ae..cd9c39f 100644 --- a/util-vserver/src/Makefile-files +++ b/util-vserver/src/Makefile-files @@ -76,7 +76,8 @@ DIETPROGS += src/chcontext-compat \ src/vshelper-sync \ src/vrsetup \ src/vserver-stat \ - src/vserver-info + src/vserver-info \ + src/vdlimit noinst_HEADERS += src/vutil.h src/vutil.p \ src/capability-compat.h \ @@ -132,6 +133,7 @@ sbin_PROGRAMS += src/chbind \ src/vdu \ src/vattribute \ src/vcontext \ + src/vdlimit \ src/vlimit \ src/vkill \ src/vnamespace \ @@ -272,6 +274,10 @@ src_rpm_fake_la_CFLAGS = $(AM_CFLAGS) src_rpm_fake_la_LDFLAGS = -module -avoid-version -rpath $(pkglibdir) src_rpm_fake_la_LIBADD = lib/libvserver.la -ldl +src_vdlimit_SOURCES = src/vdlimit.c +src_vdlimit_LDADD = $(VSERVER_LDADDS) +src_vdlimit_LDFLAGS = $(VSERVER_LDFLGS) + EXTRA_PROGRAMS += $(src_sbin_CXX_PROGS) $(src_pkglib_CXX_PROGS) TESTS_ENVIRONMENT += srctestsuitedir=$(top_builddir)/src/testsuite diff --git a/util-vserver/src/vdlimit.c b/util-vserver/src/vdlimit.c new file mode 100644 index 0000000..e52de01 --- /dev/null +++ b/util-vserver/src/vdlimit.c @@ -0,0 +1,275 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2005 Enrico Scholz +// +// 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; version 2 of the License. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "util.h" +#include +#include + +#include + +#include +#include +#include +#include +#include + +#define ENSC_WRAPPERS_PREFIX "vdlimit: " +#define ENSC_WRAPPERS_UNISTD 1 +#define ENSC_WRAPPERS_VSERVER 1 +#include + +#define CMD_HELP 0x1000 +#define CMD_VERSION 0x1001 + +int wrapper_exit_code = 1; + +struct option const +CMDLINE_OPTIONS[] = { + { "help", no_argument, 0, CMD_HELP }, + { "version", no_argument, 0, CMD_VERSION }, + { "xid", required_argument, 0, 'x' }, + { "set", required_argument, 0, 's' }, + { "remove", no_argument, 0, 'd' }, + { "flags", required_argument, 0, 'f' }, + {0,0,0,0} +}; + +static void +showHelp(int fd, char const *cmd) +{ + WRITE_MSG(fd, "Usage: "); + WRITE_STR(fd, cmd); + WRITE_MSG(fd, + " --xid [--flags ] (--set =|--remove) \n" + "\n" + " --set|-s = ... set to , where limit is \n" + " one of: space_used, space_total, inodes_used,\n" + " inodes_total, reserved\n" + " --remove|-d ... removes the disk limit for from \n" + "\n" + "Please report bugs to " PACKAGE_BUGREPORT "\n"); + + exit(0); +} + +static void +showVersion() +{ + WRITE_MSG(1, + "vdlimit " VERSION " -- manages disk limits\n" + "This program is part of " PACKAGE_STRING "\n\n" + "Copyright (C) 2005 Enrico Scholz\n" + VERSION_COPYRIGHT_DISCLAIMER); + exit(0); +} + +static void +setDlimit(char const *filename, xid_t xid, uint32_t flags, struct vc_ctx_dlimit const *limit) +{ + if (vc_get_dlimit(filename, xid, flags, 0) == -1) { + if (vc_add_dlimit(filename, xid, flags) == -1) { + perror(ENSC_WRAPPERS_PREFIX "vc_add_dlimit()"); + exit(wrapper_exit_code); + } + } + if (vc_set_dlimit(filename, xid, flags, limit) == -1) { + perror(ENSC_WRAPPERS_PREFIX "vc_set_dlimit()"); + exit(wrapper_exit_code); + } +} + +static void +remDlimit(char const *filename, xid_t xid, uint32_t flags) +{ + if (vc_rem_dlimit(filename, xid, flags) == -1) { + perror(ENSC_WRAPPERS_PREFIX "vc_rem_dlimit()"); + exit(wrapper_exit_code); + } +} + +static void +writeInt(int fd, char const *prefix, int val) +{ + char buf[sizeof(val)*3 + 2]; + size_t len = utilvserver_fmt_int(buf, val); + + if (prefix) + WRITE_STR(fd, prefix); + (void)write(fd, buf, len); +} + +static void +printDlimit(char const *filename, xid_t xid, uint32_t flags, bool formatted) +{ + struct vc_ctx_dlimit limit; + + if (vc_get_dlimit(filename, xid, flags, &limit) == -1) { + perror(ENSC_WRAPPERS_PREFIX "vc_get_dlimit()"); + exit(wrapper_exit_code); + } + + if (formatted) { + writeInt (1, 0, xid); + WRITE_MSG(1, " "); + WRITE_STR(1, filename); + writeInt (1, "\nspace_used=", limit.space_used); + writeInt (1, "\nspace_total=", limit.space_total); + writeInt (1, "\ninodes_used=", limit.inodes_used); + writeInt (1, "\ninodes_total=", limit.inodes_total); + writeInt (1, "\nreserved=", limit.reserved); + WRITE_MSG(1, "\n"); + } + else { + writeInt (1, 0, xid); + writeInt (1, " ", limit.space_used); + writeInt (1, " ", limit.space_total); + writeInt (1, " ", limit.inodes_used); + writeInt (1, " ", limit.inodes_total); + writeInt (1, " ", limit.reserved); + WRITE_MSG(1, " "); + WRITE_STR(1, filename); + WRITE_MSG(1, "\n"); + } +} + + +static bool +setDLimitField(struct vc_ctx_dlimit *dst, char const *opt) +{ + uint_least32_t *ptr; + char const * const orig_opt = opt; + +#define GET_VAL_PTR(CMP, VAL) \ + (strncmp(opt, CMP "=", sizeof(CMP))==0) ? \ + (opt+=sizeof(CMP), &VAL) : 0 + + if ((ptr=GET_VAL_PTR("space_used", dst->space_used))!=0) {} + else if ((ptr=GET_VAL_PTR("space_total", dst->space_total))!=0) {} + else if ((ptr=GET_VAL_PTR("inodes_used", dst->inodes_used))!=0) {} + else if ((ptr=GET_VAL_PTR("inodes_total", dst->inodes_total))!=0) {} + else if ((ptr=GET_VAL_PTR("reserved", dst->reserved))!=0) {} + else ptr=0; + +#undef GET_VAL_PTR + + if (ptr!=0 && *ptr==VC_CDLIM_KEEP) { + char *endptr; + long val = strtol(opt, &endptr, 0); + + if (*opt==0 || *endptr!='\0') { + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "can not parse number in '"); + WRITE_STR(2, orig_opt); + WRITE_MSG(2, "'\n"); + return false; + } + + *ptr = val; + } + else if (ptr!=0) { + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "value already set in '"); + WRITE_STR(2, orig_opt); + WRITE_MSG(2, "'\n"); + return false; + } + else { + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "unknown limit in '"); + WRITE_STR(2, orig_opt); + WRITE_MSG(2, "'\n"); + return false; + } + + return true; +} + +int main(int argc, char *argv[]) +{ + bool do_set = false; + bool do_remove = false; + xid_t xid = VC_NOCTX; + uint32_t flags = 0; + char *endptr; + int sum = 0; + + struct vc_ctx_dlimit limit = { + .space_used = VC_CDLIM_KEEP, + .space_total = VC_CDLIM_KEEP, + .inodes_used = VC_CDLIM_KEEP, + .inodes_total = VC_CDLIM_KEEP, + .reserved = VC_CDLIM_KEEP + }; + + while (1) { + int c = getopt_long(argc, argv, "+x:s:df:", CMDLINE_OPTIONS, 0); + if (c==-1) break; + + switch (c) { + case CMD_HELP : showHelp(1, argv[0]); + case CMD_VERSION : showVersion(); + case 'x' : xid = Evc_xidopt2xid(optarg, true); break; + case 's' : + if (!setDLimitField(&limit, optarg)) + return EXIT_FAILURE; + else + do_set = true; + break; + case 'd' : do_remove = true; break; + case 'f' : + { + flags = strtol(optarg, &endptr, 0); + if ((flags == 0 && errno != 0) || *endptr != '\0') { + WRITE_MSG(2, "Invalid flags argument: '"); + WRITE_STR(2, optarg); + WRITE_MSG(2, "'; try '--help' for more information\n"); + return EXIT_FAILURE; + } + } + break; + + default : + WRITE_MSG(2, "Try '"); + WRITE_STR(2, argv[0]); + WRITE_MSG(2, " --help' for more information.\n"); + return EXIT_FAILURE; + break; + } + } + + sum = ((do_set ? 1 : 0) + (do_remove ? 1 : 0)); + + if (sum>1) + WRITE_MSG(2, "Can not specify multiple operations; try '--help' for more information\n"); + else if (optind==argc) + WRITE_MSG(2, "No mount point specified; try '--help' for more information\n"); + else if (xid==VC_NOCTX) + WRITE_MSG(2, "No xid specified; try '--help' for more information\n"); + else { + for (; optind < argc; ++optind) { + if (do_set) setDlimit(argv[optind], xid, flags, &limit); + else if (do_remove) remDlimit(argv[optind], xid, flags); + else printDlimit(argv[optind], xid, flags, true); + } + + return EXIT_SUCCESS; + } + + return EXIT_FAILURE; +} -- 1.8.1.5