Quotas not enforced #3078

Closed
michaelrsweet opened this Issue Jan 28, 2009 · 10 comments

Comments

Projects
None yet
1 participant
Collaborator

michaelrsweet commented Jan 28, 2009

Version: 1.3.9
CUPS.org User: twaugh.redhat

Quotas are not enforced because the current quota usage is not correctly calculated.

When a job is not loaded in memory, job->attrs is NULL and so time-at-completion, time-at-processing, and time-at-creation attributes will not be found. This causes cupsdUpdateQuota to break out of the quota recalculation loop having reset the current usage to 0.

Here is a patch to attempt to load the job first.

Collaborator

michaelrsweet commented Jan 28, 2009

CUPS.org User: mike

Fixed in Subversion repository.

Collaborator

michaelrsweet commented Jan 28, 2009

CUPS.org User: mike

... and the 1.3 patch...

Collaborator

michaelrsweet commented Oct 23, 2009

CUPS.org User: jpopelka

I think there's a bug in str3078.patch
here
@@ -1284,7 +1258,7 @@
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Ran out of memory for job file types!",
job->id);

  • return;
    
  • return (1);
    
    }

I think there should be

  • return (0);
    
    because cupsdLoadJob() returns 1 on success and 0 on failure.
Collaborator

michaelrsweet commented Oct 23, 2009

CUPS.org User: twaugh.redhat

To properly treat it as a failure and free the resources it would need to be 'goto error;' i think.

Collaborator

michaelrsweet commented Oct 23, 2009

CUPS.org User: mike

Jiri: The current code for cupsdLoadJob() returns 0, not 1.

Tim: We don't want to unlink the job history file if we run out of memory, so "goto error" is not appropriate.

Collaborator

michaelrsweet commented Oct 26, 2009

CUPS.org User: twaugh.redhat

Jiri: The current code for cupsdLoadJob() returns 0, not 1.

Are you sure? I'm looking at line 1660 of scheduler/job.c in branch-1.4.

if (!compressions || !filetypes)
{
  cupsdLogMessage(CUPSD_LOG_ERROR,
                  "[Job %d] Ran out of memory for job file types!",
                  job->id);

return (1);
}

Collaborator

michaelrsweet commented Oct 26, 2009

CUPS.org User: mike

Tim: Can you file a new bug on that specific issue? It is unrelated to this bug, and we can hash out what the correct behavior should be in the face of an out-of-memory condition...

Collaborator

michaelrsweet commented Oct 26, 2009

"0001-Load-job-attributes-when-recalculating-quotas.patch":

From 450f4bf0cb6498c7aa35809a6c58978357b20594 Mon Sep 17 00:00:00 2001
From: Tim Waugh twaugh@redhat.com
Date: Tue, 27 Jan 2009 17:04:05 +0000
Subject: [PATCH] Load job attributes when recalculating quotas.

Previously, the first job not loaded would cause the recalculation

to stop, effectively resetting quotas.

scheduler/quotas.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/scheduler/quotas.c b/scheduler/quotas.c
index 0f75e62..dc195ee 100644
--- a/scheduler/quotas.c
+++ b/scheduler/quotas.c
@@ -159,6 +159,15 @@ cupsdUpdateQuota(
strcasecmp(job->username, q->username) != 0)
continue;

  • if (!job->attrs)
  • {
  •  cupsdLoadJob (job);
    
  •  if (!job->attrs)
    
  • /* This job has already been purged. */
  • continue;
  • }

if ((attr = ippFindAttribute(job->attrs, "time-at-completion",
IPP_TAG_INTEGER)) == NULL)
if ((attr = ippFindAttribute(job->attrs, "time-at-processing",

1.6.0.6

Collaborator

michaelrsweet commented Oct 26, 2009

"str3078.patch":

Index: scheduler/quotas.c

--- scheduler/quotas.c (revision 8293)
+++ scheduler/quotas.c (working copy)
@@ -3,7 +3,7 @@
*

  • Quota routines for the Common UNIX Printing System (CUPS).
  • * Copyright 2007 by Apple Inc.
  • * Copyright 2007-2009 by Apple Inc.
  • Copyright 1997-2007 by Easy Software Products.
  • These coded instructions, statements, and computer programs are the
    @@ -155,10 +155,22 @@
    job;
    job = (cupsd_job_t *)cupsArrayNext(Jobs))
    {
  • /*
  • * We only care about the current printer/class and user...
  • */
if (strcasecmp(job->dest, p->name) != 0 ||
   strcasecmp(job->username, q->username) != 0)
continue;
  • /*
  • * Make sure attributes are loaded; we always call cupsdLoadJob() to ensure
  • * the access_time member is updated so the job isn't unloaded right away...
  • */
  • if (!cupsdLoadJob(job))

  •  continue;
    

    if ((attr = ippFindAttribute(job->attrs, "time-at-completion",
    IPP_TAG_INTEGER)) == NULL)
    if ((attr = ippFindAttribute(job->attrs, "time-at-processing",
    @@ -166,11 +178,22 @@
    attr = ippFindAttribute(job->attrs, "time-at-creation",
    IPP_TAG_INTEGER);

  • if (attr == NULL)

  •  break;
    
  • if (!attr)

  • {

  • /*
    
  •  \* This should never happen since cupsdLoadJob() checks for
    
  •  \* time-at-creation, but if it does just ignore this job...
    
  •  */
    
  •  continue;
    
  • }

if (attr->values[0].integer < curtime)
{

  • /*
    
  •  \* This job is too old to count towards the quota, ignore it...
    
  •  */
    
    • if (JobAutoPurge)
      cupsdCancelJob(job, 1, IPP_JOB_CANCELED);

Index: scheduler/job.c

--- scheduler/job.c (revision 8293)
+++ scheduler/job.c (working copy)
@@ -1056,7 +1056,7 @@

  • 'cupsdLoadJob()' - Load a single job...
    */

-void
+int /* O - 1 on success, 0 on failure /
cupsdLoadJob(cupsd_job_t *job) /
I - Job /
{
char jobfile[1024]; /
Job filename */
@@ -1074,14 +1074,14 @@
if (job->state_value > IPP_JOB_STOPPED)
job->access_time = time(NULL);

  • return;
  • return (1);
    }

if ((job->attrs = ippNew()) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Ran out of memory for job attributes!", job->id);

  • return;
  • return (0);
    }

/*
@@ -1096,9 +1096,7 @@
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Unable to open job control file "%s" - %s!",
job->id, jobfile, strerror(errno));

  • ippDelete(job->attrs);
  • job->attrs = NULL;
  • return;
  • goto error;
    }

if (ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, job->attrs) != IPP_DATA)
@@ -1107,10 +1105,7 @@
"[Job %d] Unable to read job control file "%s"!", job->id,
jobfile);
cupsFileClose(fp);

  • ippDelete(job->attrs);
  • job->attrs = NULL;
  • unlink(jobfile);
  • return;
  • goto error;
    }

cupsFileClose(fp);
@@ -1124,10 +1119,7 @@
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Missing or bad time-at-creation attribute in "
"control file!", job->id);

  • ippDelete(job->attrs);
  • job->attrs = NULL;
  • unlink(jobfile);
  • return;
  • goto error;
    }

if ((job->state = ippFindAttribute(job->attrs, "job-state",
@@ -1136,10 +1128,7 @@
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Missing or bad job-state attribute in control "
"file!", job->id);

  • ippDelete(job->attrs);
  • job->attrs = NULL;
  • unlink(jobfile);
  • return;
  • goto error;
    }

job->state_value = (ipp_jstate_t)job->state->values[0].integer;
@@ -1152,10 +1141,7 @@
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] No job-printer-uri attribute in control file!",
job->id);

  •  ippDelete(job->attrs);
    
  •  job->attrs = NULL;
    
  •  unlink(jobfile);
    
  •  return;
    
  •  goto error;
    

    }

    if ((dest = cupsdValidateDest(attr->values[0].string.text, &(job->dtype),
    @@ -1164,10 +1150,7 @@
    cupsdLogMessage(CUPSD_LOG_ERROR,
    "[Job %d] Unable to queue job for destination "%s"!",
    job->id, attr->values[0].string.text);

  •  ippDelete(job->attrs);
    
  •  job->attrs = NULL;
    
  •  unlink(jobfile);
    
  •  return;
    
  •  goto error;
    

    }

    cupsdSetString(&job->dest, dest);
    @@ -1177,10 +1160,7 @@
    cupsdLogMessage(CUPSD_LOG_ERROR,
    "[Job %d] Unable to queue job for destination "%s"!",
    job->id, job->dest);

  • ippDelete(job->attrs);

  • job->attrs = NULL;

  • unlink(jobfile);

  • return;

  • goto error;
    }

job->sheets = ippFindAttribute(job->attrs, "job-media-sheets-completed",
@@ -1195,10 +1175,7 @@
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Missing or bad job-priority attribute in "
"control file!", job->id);

  •  ippDelete(job->attrs);
    
  •  job->attrs = NULL;
    
  •  unlink(jobfile);
    
  •  return;
    
  •  goto error;
    

    }

    job->priority = attr->values[0].integer;
    @@ -1212,10 +1189,7 @@
    cupsdLogMessage(CUPSD_LOG_ERROR,
    "[Job %d] Missing or bad job-originating-user-name "
    "attribute in control file!", job->id);

  •  ippDelete(job->attrs);
    
  •  job->attrs = NULL;
    
  •  unlink(jobfile);
    
  •  return;
    
  •  goto error;
    

    }

    cupsdSetString(&job->username, attr->values[0].string.text);
    @@ -1284,7 +1258,7 @@
    cupsdLogMessage(CUPSD_LOG_ERROR,
    "[Job %d] Ran out of memory for job file types!",
    job->id);

  • return;
    
  • return (1);
    

    }

     job->compressions = compressions;
    

    @@ -1342,6 +1316,18 @@
    }

    job->access_time = time(NULL);

  • return (1);

  • /*
  • * If we get here then something bad happened...
  • */
  • error:
  • ippDelete(job->attrs);
  • job->attrs = NULL;
  • unlink(jobfile);
  • return (0);
    }

Index: scheduler/job.h

--- scheduler/job.h (revision 8293)
+++ scheduler/job.h (working copy)
@@ -3,7 +3,7 @@
*

  • Print job definitions for the Common UNIX Printing System (CUPS) scheduler.
  • * Copyright 2007-2008 by Apple Inc.
  • * Copyright 2007-2009 by Apple Inc.
  • Copyright 1997-2007 by Easy Software Products, all rights reserved.
  • These coded instructions, statements, and computer programs are the
    @@ -117,7 +117,7 @@
    extern int cupsdGetUserJobCount(const char *username);
    extern void cupsdHoldJob(cupsd_job_t *job);
    extern void cupsdLoadAllJobs(void);
    -extern void cupsdLoadJob(cupsd_job_t *job);
    +extern int cupsdLoadJob(cupsd_job_t *job);
    extern void cupsdMoveJob(cupsd_job_t *job, cupsd_printer_t *p);
    extern void cupsdReleaseJob(cupsd_job_t *job);
    extern void cupsdRestartJob(cupsd_job_t *job);
Collaborator

michaelrsweet commented Oct 26, 2009

"str3078-1.3.patch":

Index: scheduler/quotas.c

--- scheduler/quotas.c (revision 8293)
+++ scheduler/quotas.c (working copy)
@@ -3,7 +3,7 @@
*

  • Quota routines for the Common UNIX Printing System (CUPS).
  • * Copyright 2007 by Apple Inc.
  • * Copyright 2007-2009 by Apple Inc.
  • Copyright 1997-2007 by Easy Software Products.
  • These coded instructions, statements, and computer programs are the
    @@ -155,10 +155,22 @@
    job;
    job = (cupsd_job_t *)cupsArrayNext(Jobs))
    {
  • /*
  • * We only care about the current printer/class and user...
  • */
if (strcasecmp(job->dest, p->name) != 0 ||
   strcasecmp(job->username, q->username) != 0)
continue;
  • /*
  • * Make sure attributes are loaded; we always call cupsdLoadJob() to ensure
  • * the access_time member is updated so the job isn't unloaded right away...
  • */
  • if (!cupsdLoadJob(job))

  •  continue;
    

    if ((attr = ippFindAttribute(job->attrs, "time-at-completion",
    IPP_TAG_INTEGER)) == NULL)
    if ((attr = ippFindAttribute(job->attrs, "time-at-processing",
    @@ -166,11 +178,22 @@
    attr = ippFindAttribute(job->attrs, "time-at-creation",
    IPP_TAG_INTEGER);

  • if (attr == NULL)

  •  break;
    
  • if (!attr)

  • {

  • /*
    
  •  \* This should never happen since cupsdLoadJob() checks for
    
  •  \* time-at-creation, but if it does just ignore this job...
    
  •  */
    
  •  continue;
    
  • }

if (attr->values[0].integer < curtime)
{

  • /*
    
  •  \* This job is too old to count towards the quota, ignore it...
    
  •  */
    
    • if (JobAutoPurge)
      cupsdCancelJob(job, 1, IPP_JOB_CANCELED);

Index: scheduler/job.c

--- scheduler/job.c (revision 8293)
+++ scheduler/job.c (working copy)
@@ -3,7 +3,7 @@
*

  • Job management routines for the Common UNIX Printing System (CUPS).
  • * Copyright 2007-2008 by Apple Inc.
  • * Copyright 2007-2009 by Apple Inc.
  • Copyright 1997-2007 by Easy Software Products, all rights reserved.
  • These coded instructions, statements, and computer programs are the
    @@ -1019,7 +1019,7 @@
  • 'cupsdLoadJob()' - Load a single job...
    */

-void
+int /* O - 1 on success, 0 on failure /
cupsdLoadJob(cupsd_job_t *job) /
I - Job /
{
char jobfile[1024]; /
Job filename */
@@ -1037,14 +1037,14 @@
if (job->state_value > IPP_JOB_STOPPED)
job->access_time = time(NULL);

  • return;
  • return (1);
    }

if ((job->attrs = ippNew()) == NULL)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Ran out of memory for job attributes!", job->id);

  • return;
  • return (0);
    }

/*
@@ -1059,9 +1059,7 @@
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Unable to open job control file "%s" - %s!",
job->id, jobfile, strerror(errno));

  • ippDelete(job->attrs);
  • job->attrs = NULL;
  • return;
  • goto error;
    }

if (ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, job->attrs) != IPP_DATA)
@@ -1070,10 +1068,7 @@
"[Job %d] Unable to read job control file "%s"!",
job->id, jobfile);
cupsFileClose(fp);

  • ippDelete(job->attrs);
  • job->attrs = NULL;
  • unlink(jobfile);
  • return;
  • goto error;
    }

cupsFileClose(fp);
@@ -1087,10 +1082,7 @@
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Missing or bad time-at-creation attribute in "
"control file!", job->id);

  • ippDelete(job->attrs);
  • job->attrs = NULL;
  • unlink(jobfile);
  • return;
  • goto error;
    }

if ((job->state = ippFindAttribute(job->attrs, "job-state",
@@ -1100,10 +1092,7 @@
"[Job %d] Missing or bad job-state attribute in "
"control file!",
job->id);

  • ippDelete(job->attrs);
  • job->attrs = NULL;
  • unlink(jobfile);
  • return;
  • goto error;
    }

job->state_value = (ipp_jstate_t)job->state->values[0].integer;
@@ -1116,10 +1105,7 @@
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] No job-printer-uri attribute in control file!",
job->id);

  •  ippDelete(job->attrs);
    
  •  job->attrs = NULL;
    
  •  unlink(jobfile);
    
  •  return;
    
  •  goto error;
    

    }

    if ((dest = cupsdValidateDest(attr->values[0].string.text, &(job->dtype),
    @@ -1128,10 +1114,7 @@
    cupsdLogMessage(CUPSD_LOG_ERROR,
    "[Job %d] Unable to queue job for destination "%s"!",
    job->id, attr->values[0].string.text);

  •  ippDelete(job->attrs);
    
  •  job->attrs = NULL;
    
  •  unlink(jobfile);
    
  •  return;
    
  •  goto error;
    

    }

    cupsdSetString(&job->dest, dest);
    @@ -1141,10 +1124,7 @@
    cupsdLogMessage(CUPSD_LOG_ERROR,
    "[Job %d] Unable to queue job for destination "%s"!",
    job->id, job->dest);

  • ippDelete(job->attrs);

  • job->attrs = NULL;

  • unlink(jobfile);

  • return;

  • goto error;
    }

job->sheets = ippFindAttribute(job->attrs, "job-media-sheets-completed",
@@ -1159,10 +1139,7 @@
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Missing or bad job-priority attribute in "
"control file!", job->id);

  •  ippDelete(job->attrs);
    
  •  job->attrs = NULL;
    
  •  unlink(jobfile);
    
  •  return;
    
  •  goto error;
    

    }

    job->priority = attr->values[0].integer;
    @@ -1176,10 +1153,7 @@
    cupsdLogMessage(CUPSD_LOG_ERROR,
    "[Job %d] Missing or bad job-originating-user-name "
    "attribute in control file!", job->id);

  •  ippDelete(job->attrs);
    
  •  job->attrs = NULL;
    
  •  unlink(jobfile);
    
  •  return;
    
  •  goto error;
    

    }

    cupsdSetString(&job->username, attr->values[0].string.text);
    @@ -1248,7 +1222,7 @@
    cupsdLogMessage(CUPSD_LOG_ERROR,
    "[Job %d] Ran out of memory for job file types!",
    job->id);

  • return;
    
  • return (1);
    

    }

     job->compressions = compressions;
    

    @@ -1304,7 +1278,20 @@
    cupsFileClose(fp);
    }
    }
    +
    job->access_time = time(NULL);

  • return (1);

  • /*
  • * If we get here then something bad happened...
  • */
  • error:
  • ippDelete(job->attrs);
  • job->attrs = NULL;
  • unlink(jobfile);
  • return (0);
    }

Index: scheduler/job.h

--- scheduler/job.h (revision 8293)
+++ scheduler/job.h (working copy)
@@ -3,7 +3,7 @@
*

  • Print job definitions for the Common UNIX Printing System (CUPS) scheduler.
  • * Copyright 2007-2008 by Apple Inc.
  • * Copyright 2007-2009 by Apple Inc.
  • Copyright 1997-2007 by Easy Software Products, all rights reserved.
  • These coded instructions, statements, and computer programs are the
    @@ -112,7 +112,7 @@
    extern int cupsdGetUserJobCount(const char *username);
    extern void cupsdHoldJob(cupsd_job_t *job);
    extern void cupsdLoadAllJobs(void);
    -extern void cupsdLoadJob(cupsd_job_t *job);
    +extern int cupsdLoadJob(cupsd_job_t *job);
    extern void cupsdMoveJob(cupsd_job_t *job, cupsd_printer_t *p);
    extern void cupsdReleaseJob(cupsd_job_t *job);
    extern void cupsdRestartJob(cupsd_job_t *job);

michaelrsweet added this to the Stable milestone Mar 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment