added *vdlimit functions + tools (patch provided by Daniel Hokka Zakrisson)
authorEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Wed, 2 Mar 2005 00:52:44 +0000 (00:52 +0000)
committerEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Wed, 2 Mar 2005 00:52:44 +0000 (00:52 +0000)
git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@1874 94cd875c-1c1d-0410-91d2-eb244daf1a30

13 files changed:
util-vserver/lib/Makefile-files
util-vserver/lib/syscall_adddlimit-v13.hc [new file with mode: 0644]
util-vserver/lib/syscall_adddlimit.c [new file with mode: 0644]
util-vserver/lib/syscall_getdlimit-v13.hc [new file with mode: 0644]
util-vserver/lib/syscall_getdlimit.c [new file with mode: 0644]
util-vserver/lib/syscall_remdlimit-v13.hc [new file with mode: 0644]
util-vserver/lib/syscall_remdlimit.c [new file with mode: 0644]
util-vserver/lib/syscall_setdlimit-v13.hc [new file with mode: 0644]
util-vserver/lib/syscall_setdlimit.c [new file with mode: 0644]
util-vserver/lib/virtual.h
util-vserver/lib/vserver.h
util-vserver/src/Makefile-files
util-vserver/src/vdlimit.c [new file with mode: 0644]

index d1a82e3..88f586a 100644 (file)
@@ -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 (file)
index 0000000..18e1a79
--- /dev/null
@@ -0,0 +1,34 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#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 (file)
index 0000000..b1a7846
--- /dev/null
@@ -0,0 +1,36 @@
+// $Id$    --*- c++ -*--
+
+// Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#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 (file)
index 0000000..f869e8b
--- /dev/null
@@ -0,0 +1,46 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#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 (file)
index 0000000..f0e9e8e
--- /dev/null
@@ -0,0 +1,37 @@
+// $Id$    --*- c++ -*--
+
+// Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#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 (file)
index 0000000..38df159
--- /dev/null
@@ -0,0 +1,34 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#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 (file)
index 0000000..6c6623d
--- /dev/null
@@ -0,0 +1,36 @@
+// $Id$   --*- c++ -*--
+
+// Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#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 (file)
index 0000000..22117a9
--- /dev/null
@@ -0,0 +1,40 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#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 (file)
index 0000000..84776e6
--- /dev/null
@@ -0,0 +1,37 @@
+// $Id$    --*- c++ -*--
+
+// Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#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));
+}
index 2f5cde4..f880c98 100644 (file)
@@ -26,5 +26,6 @@
 #include <kernel/namespace.h>
 #include <kernel/inode.h>
 #include <kernel/sched.h>
+#include <kernel/dlimit.h>
 
 #endif //  H_UTIL_VSERVER_LIB_VIRTUAL_H
index 5bd22a3..276d876 100644 (file)
@@ -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
index 1a976ae..cd9c39f 100644 (file)
@@ -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 (file)
index 0000000..e52de01
--- /dev/null
@@ -0,0 +1,275 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// 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 <config.h>
+#endif
+
+#include "util.h"
+#include <lib_internal/sys_clone.h>
+#include <lib/internal.h>
+
+#include <vserver.h>
+
+#include <getopt.h>
+#include <libgen.h>
+#include <errno.h>
+#include <signal.h>
+#include <sched.h>
+
+#define ENSC_WRAPPERS_PREFIX   "vdlimit: "
+#define ENSC_WRAPPERS_UNISTD   1
+#define ENSC_WRAPPERS_VSERVER  1
+#include <wrappers.h>
+
+#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 <xid> [--flags <flags>] (--set <limit>=<value>|--remove) <mount point>\n"
+           "\n"
+           "    --set|-s <limit>=<value>  ...  set <limit> to <value>, where limit is \n"
+           "                           one of: space_used, space_total, inodes_used,\n"
+           "                           inodes_total, reserved\n"
+           "    --remove|-d       ...  removes the disk limit for <xid> from <mount point>\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;
+}