I work for a hosting company and for some time we have had issues with quotas not being properly enforceable.
After being somewhat sick of it I decided to patch our bacula to support quotas (3.0.2). Now, I am not a C coder by any means and dont expect what i've written to be good enough for general release. But I am testing this patch on a trial backup server and will be monitoring it for the next week. I am aware this is not the most up to date version of bacula and as such I dont expect this to be accepted. However I do intend on forward porting it but first I am needing some advise regarding the patch, how I am doing this and where and what problems I might come up against. Some of the things I would like pointers on - The placement of some of the functions and the files they are in. - The most appropriate spot to place functions and if I have put them in the right place. - Cosmetic and coding designs being incorrect and where to correct them. - How to use bregex to parse the jobbytes value I am getting back. - Any other criticisms. Again I do not consider myself a C programmer so am open to much criticism in this regard. I dont think I've made this production quality at all. How this works. The Client Resource can be updated with four configuration options: Hard Quota = <Y bytes> Soft Quota = <X bytes> Soft Quota Grace Period = <X period> Strict Quota = <yes|no> Hard quota: The limit that a job must be canceled at after over-running this value. Soft Quota: The limit for when bacula starts warning about quotas and initiating a grace period. Soft Quota Grace Period: The amount of time bacula will permit going over the soft quota. Strict Quota: This changes the behaviour of the soft quota enforcement. With this set to 'yes' after gracetime expires a client must be below his soft quota to continue to have backups. With this set to no the client is enforced up to the maximum quota they had just prior to the softquota gracetime expiring. How it works. Aside from the various function calls performed in two places and the DB functions the basic idea is this: A job runs. Hard / Soft quotas are checked. If over quota at this point the job cancels. This prevents a job running immediately and providing pointless timeouts. When the job starts, when the scheduling watchdog kicks in and the job is running a "status client" command is issued to the client. The jobbytes value parsed and the quota value determined by the sum of all previous jobs within the job retention period of that client plus the current jobs jobbytes value. If it goes over then the job is canceled. I altered the backup report slightly to report quotas, current quota amount and the quota limits per job run to make it easier to determine the current quota the user had assigned. Finally I added a new option for bconsole purge->quotas. This zeroes the values in the quota table for that row effectively resetting quotas. Database changes. I added a new table called Quota which contains the clients id, a softquota and gracetime value. These are used to enforce soft quotas when strict quota checking is off and to store the gracetime period. Its early days running this patch on our own systems at the moment but we expect this to reduce the number of failed jobs waiting to time out on our system by about 90%. Supplied is the patch and the sql dump. Things I would be keen on adding is a gracetime value to the job report (how much time left) but my crappy coding in time manipulation in C is holding me back. Also I want to change the jobbytes parser (kept in fs_cmds.c) to use bregex as I expect it will be massively less uglier and more successful at parsing the string I want. There is also some portions of the code I simply dont properly understand that well which I have more or less fudged from other functions. In particular is the jobbytes parser (again) regarding copying the jcr->client record in correctly. I am also interested in your feedback in regards to the idea that Im affectively running status client every minute for all running jobs that support quotas. Does this pose any long term problems? It was unavoidable to be honest but I think it probably does scale into the thousands still. Also I added then didnt use some variables. Bad practice to leave them in I know! I'll be removing these for proper production use. Again, I know this is bacula 3 and I know that wont impress you lot - it just makes things harder for you to review - but I will be happy to forward port this myself however rather to do this properly and to do it properly requires your input. NOTE: This version contains a openssl patch made to run in fedora. It doesnt affect compilation of redhat boxes but fedora wouldnt let me compile this without it!
bacula-quotas.patch.gz
Description: GNU Zip compressed data
-- MySQL dump 10.11 -- -- Host: localhost Database: bacula -- ------------------------------------------------------ -- Server version 5.0.77 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `Quota` -- DROP TABLE IF EXISTS `Quota`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; CREATE TABLE `Quota` ( `ClientId` int(10) unsigned default NULL, `GraceTime` bigint(20) default '0', `QuotaLimit` bigint(20) unsigned default '0', `id` int(11) NOT NULL auto_increment, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=23 DEFAULT CHARSET=latin1; SET character_set_client = @saved_cs_client; /*!40103 SET time_zo...@old_time_zone */; /*!40101 SET sql_mo...@old_sql_mode */; /*!40014 SET foreign_key_chec...@old_foreign_key_checks */; /*!40014 SET unique_chec...@old_unique_checks */; /*!40101 SET character_set_clie...@old_character_set_client */; /*!40101 SET character_set_resul...@old_character_set_results */; /*!40101 SET collation_connecti...@old_collation_connection */; /*!40111 SET sql_not...@old_sql_notes */; -- Dump completed on 2010-07-05 21:25:10
------------------------------------------------------------------------------ This SF.net email is sponsored by Sprint What will you do first with EVO, the first 4G phone? Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________ Bacula-devel mailing list Bacula-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bacula-devel