From 903ac95d92d316979e0b2e5073d4252ac3af63b5 Mon Sep 17 00:00:00 2001 From: Marc Fiuczynski Date: Tue, 21 Sep 2004 01:06:06 +0000 Subject: [PATCH] vdlimit is a replacement for the prior tools used to set disklimits. The prior tools appear to have been a hack on top of the quota support. NOTE that the vdlimit code was taken from Herbert Poetzl's Experimental website. It is vdlimit 0.01. The code didn't compile and was standalone. I integrated it with util-vserver, but it needs further integration. Have already sent Herbert email about this and another minor problem. --- lib/virtual.h | 2 + src/Makefile-files | 6 +- src/dlimit.h | 76 ++++++++++++++++++++ src/vdlimit.c | 174 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 src/dlimit.h create mode 100644 src/vdlimit.c diff --git a/lib/virtual.h b/lib/virtual.h index f55e6dd..f12b3d7 100644 --- a/lib/virtual.h +++ b/lib/virtual.h @@ -47,6 +47,8 @@ #define VC_CAT_PROCTRL 12 +#define VC_CAT_DLIMIT 36 + #define VC_CAT_RLIMIT 60 #define VC_CAT_SYSTEST 61 diff --git a/src/Makefile-files b/src/Makefile-files index 2f8be51..a990434 100644 --- a/src/Makefile-files +++ b/src/Makefile-files @@ -40,7 +40,8 @@ src_sbin_PRGS = src/chbind \ src/rebootmgr \ src/reducecap \ src/vdu \ - src/vsh \ + src/vdu \ + src/vdlimit \ src/vfiles \ src/vkill \ src/vserver-stat @@ -83,6 +84,9 @@ src_vkill_CPPFLAGS = $(AM_CPPFLAGS) -DLEGACYDIR=\"$(legacydir)\" src_vsh_SOURCES = src/vsh.c src/planetlab.c src_vsh_LDADD = lib/libvserver.a +src_vdlimit_SOURCES = src/vdlimit.c +src_vdlimit_LDADD = lib/libvserver.a + src_showattr_SOURCES = src/showattr.c src_showperm_SOURCES = src/showperm.c src_vbuild_SOURCES = src/vbuild.cc src/vutil.cc diff --git a/src/dlimit.h b/src/dlimit.h new file mode 100644 index 0000000..5cbb1a1 --- /dev/null +++ b/src/dlimit.h @@ -0,0 +1,76 @@ +#ifndef _VX_DLIMIT_H +#define _VX_DLIMIT_H + +#include "virtual.h" +// #include "switch.h" + +/* inode vserver commands */ + +#define VCMD_add_dlimit VC_CMD(DLIMIT, 1, 0) +#define VCMD_rem_dlimit VC_CMD(DLIMIT, 2, 0) + +#define VCMD_set_dlimit VC_CMD(DLIMIT, 5, 0) +#define VCMD_get_dlimit VC_CMD(DLIMIT, 6, 0) + + +struct vcmd_ctx_dlimit_base_v0 { + char *name; + uint32_t flags; +}; + +struct vcmd_ctx_dlimit_v0 { + char *name; + uint32_t space_used; /* used space in kbytes */ + uint32_t space_total; /* maximum space in kbytes */ + uint32_t inodes_used; /* used inodes */ + uint32_t inodes_total; /* maximum inodes */ + uint32_t reserved; /* reserved for root in % */ + uint32_t flags; +}; + +#define CDLIM_UNSET (0ULL) +#define CDLIM_INFINITY (~0ULL) +#define CDLIM_KEEP (~1ULL) + + +#ifdef __KERNEL__ + +struct super_block; + +struct dl_info { + struct hlist_node dl_hlist; /* linked list of contexts */ + struct rcu_head dl_rcu; /* the rcu head */ + xid_t dl_xid; /* context id */ + atomic_t dl_usecnt; /* usage count */ + atomic_t dl_refcnt; /* reference count */ + + struct super_block *dl_sb; /* associated superblock */ + + struct rw_semaphore dl_sem; /* protect the values */ + + uint64_t dl_space_used; /* used space in bytes */ + uint64_t dl_space_total; /* maximum space in bytes */ + uint32_t dl_inodes_used; /* used inodes */ + uint32_t dl_inodes_total; /* maximum inodes */ + + unsigned int dl_nrlmult; /* non root limit mult */ +}; + +extern void rcu_free_dl_info(void *); +extern void unhash_dl_info(struct dl_info *); + +struct kstatfs; + +extern void vx_vsi_statfs(struct super_block *, struct kstatfs *); + + +extern int vc_add_dlimit(uint32_t, void __user *); +extern int vc_rem_dlimit(uint32_t, void __user *); + +extern int vc_set_dlimit(uint32_t, void __user *); +extern int vc_get_dlimit(uint32_t, void __user *); + + +#endif /* __KERNEL__ */ + +#endif /* _VX_DLIMIT_H */ diff --git a/src/vdlimit.c b/src/vdlimit.c new file mode 100644 index 0000000..beea0c5 --- /dev/null +++ b/src/vdlimit.c @@ -0,0 +1,174 @@ + +/* +** (c) 2004 Herbert Poetzl +** +** V0.01 ioctls so far +** +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "compat.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vserver.h" +#include "vserver-internal.h" +#include "dlimit.h" + +#ifdef O_LARGEFILE +#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE) +#else +#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK) +#endif + +static char err_flag = 0; + +static char opt_xid = 0; +static char opt_flag = 0; +static char opt_vers = 0; +static char opt_add = 0; +static char opt_rem = 0; +static char opt_set = 0; + +static char * cmd_name = NULL; +static char * set_arg = NULL; + +static int num_xid = 0; +static int num_flag = 0; + + + + +#define OPTIONS "+hadf:x:S:V" + +int main(int argc, char *argv[]) +{ + extern int optind; + extern char *optarg; + char c, errflg = 0; + int r; + + + cmd_name = argv[0]; + while ((c = getopt(argc, argv, OPTIONS)) != EOF) { + switch (c) { + case 'h': + fprintf(stderr, + "This is %s " VERSION "\n" + "options are:\n" + "-h print this help message\n" + "-a add dlimit entry\n" + "-d delete dlimit entry\n" + "-f flag value in decimal\n" + "-x context id\n" + "-S current/limit values\n" + "-V verify interface version\n" + "-- end of options\n" + ,cmd_name); + exit(0); + break; + case 'a': + opt_add = 1; + break; + case 'd': + opt_rem = 1; + break; + case 'f': + num_flag = atol(optarg); + opt_flag = 1; + break; + case 'x': + num_xid = atol(optarg); + opt_xid = 1; + break; + case 'S': + set_arg = optarg; + opt_set = 1; + break; + case 'V': + opt_vers = 1; + break; + case '?': + default: + errflg++; + break; + } + } + if (errflg) { + fprintf(stderr, + "Usage: %s -[" OPTIONS "] ...\n" + "%s -h for help.\n", + cmd_name, cmd_name); + exit(2); + } + + if (opt_vers) { + r = vc_get_version(); + if (r<0) + perror("vc_get_version"); + else + printf("version: %04x:%04x\n", + (r>>16)&0xFFFF, r&0xFFFF); + } + + for (; optind < argc; optind++) { + struct vcmd_ctx_dlimit_base_v0 init; + struct vcmd_ctx_dlimit_v0 data; + + init.name = argv[optind]; + init.flags = num_flag; + + if (opt_rem) { + r = vserver(VCMD_rem_dlimit, num_xid, &init); + if (r<0) + perror("vc_rem_dlimit"); + } + if (opt_add) { + r = vserver(VCMD_add_dlimit, num_xid, &init); + if (r<0) + perror("vc_add_dlimit"); + } + + memset(&data, 0, sizeof(data)); + data.name = argv[optind]; + data.flags = num_flag; + + if (opt_set) { + sscanf(set_arg, "%u,%u,%u,%u,%u", + &data.space_used, &data.space_total, + &data.inodes_used, &data.inodes_total, + &data.reserved); + + r = vserver(VCMD_set_dlimit, num_xid, &data); + if (r<0) + perror("vc_set_dlimit"); + } + + memset(&data, 0, sizeof(data)); + data.name = argv[optind]; + data.flags = num_flag; + + r = vserver(VCMD_get_dlimit, num_xid, &data); + if (r<0) + perror("vc_get_dlimit"); + + printf("%s: %u,%u,%u,%u,%u\n", argv[optind], + data.space_used, data.space_total, + data.inodes_used, data.inodes_total, + data.reserved); + } + + exit((err_flag)?1:0); +} + -- 2.43.0