Ticket #3: munin-fastcgi-ticket3.diff

File munin-fastcgi-ticket3.diff, 8.6 kB (added by blueyed, 3 years ago)

Patch against SVN trunk as described in the previous comment

  • server/munin-graph.in

    old new  
    862862        RRDs::graph (@complete); 
    863863        if (my $ERROR = RRDs::error) { 
    864864            logger ("Unable to graph ". munin_get_picture_filename ($service, $time) . ": $ERROR"); 
    865         } elsif ($list_images) { 
    866             # Command-line option to list images created 
    867             print munin_get_picture_filename ($service, $time),"\n"; 
     865        } else { 
     866            # "touch" the file, so that munin-cgi-graph can see the "last update"/modified status: 
     867            utime $lastupdate, $lastupdate, munin_get_picture_filename($service, $time); 
     868 
     869            if ($list_images) { 
     870                # Command-line option to list images created 
     871                print munin_get_picture_filename ($service, $time),"\n"; 
     872            } 
    868873        } 
    869874    } 
    870875 
     
    944949 
    945950            if (my $ERROR = RRDs::error) { 
    946951                logger ("Unable to graph ". munin_get_picture_filename ($service, $time) . ": $ERROR"); 
    947             } elsif ($list_images) { 
    948                 # Command-line option to list images created 
    949                 print munin_get_picture_filename ($service, $time, 1),"\n"; 
     952            } else { 
     953                # "touch" the file, so that munin-cgi-graph can see the "last update"/modified status: 
     954                utime $lastupdate, $lastupdate, munin_get_picture_filename($service, $time); 
     955 
     956                if ($list_images) { 
     957                    # Command-line option to list images created 
     958                    print munin_get_picture_filename ($service, $time),"\n"; 
     959                } 
    950960            } 
    951961        } 
    952962    } 
  • server/munin-cgi-graph.in

    old new  
    3030use Date::Manip; 
    3131use POSIX qw(strftime); 
    3232use IPC::SysV qw(IPC_CREAT); 
     33use CGI::Fast; 
    3334 
    3435my $GRAPHER = "@@LIBDIR@@/munin-graph"; 
    3536my $conffile = "@@CONFDIR@@/munin.conf"; 
     
    5657my $serv  = ""; 
    5758my $dom   = ""; 
    5859my $lock  = ""; 
    59 my $IPC_KEY = 89340; 
     60my $IPC_KEY = 9340; 
    6061 
    6162my $config = &munin_readconfig ($conffile); 
    6263 
    63 my $path = $ENV{PATH_INFO} || ""; 
    64 $path =~ s/^\///; 
    65 ($dom, $host, $serv) = split /\//, $path; 
    66 ($serv, $scale) = split /-/, $serv, 2; 
    67 $scale =~ s/\.png$//; 
    6864 
    69 &verify_parameters ($dom, $host, $serv, $scale); 
     65# BEGIN FAST-CGI LOOP: 
     66while (new CGI::Fast) 
     67
     68    my $path = $ENV{PATH_INFO} || ""; 
     69    $path =~ s/^\///; 
     70    ($dom, $host, $serv) = split /\//, $path; 
     71    ($serv, $scale) = split /-/, $serv, 2; 
     72    $scale =~ s/\.png$//; 
    7073 
    71 my $filename = get_picture_filename ($config, $dom, $host, $serv, $scale); 
     74    if (! &verify_parameters ($dom, $host, $serv, $scale)) 
     75    { 
     76        print "Status: 500\n"; 
     77        print "Content-Type: text/html\n"; 
     78        print "\n"; 
     79        print "Invalid parameters!"; 
     80        next; 
     81    } 
    7282 
    73 my $time = time
     83    my $filename = get_picture_filename ($config, $dom, $host, $serv, $scale)
    7484 
    75 if (-f $filename) 
    76 
    77     my @sstats = stat ($filename); 
    78     my $slast_modified = strftime ("%a, %d %b %Y %H:%M:%S %Z", localtime ($sstats[9])); 
     85    my $time = time; 
    7986 
    80     if (defined $ENV{HTTP_IF_MODIFIED_SINCE} and  
    81         !&modified (gmtime(time+($period{$scale}-($time%$period{$scale}))), 
    82                     $sstats[9]-1)) { 
    83         print "Status: 304\n"; 
    84         print "Content-Type: image/png\n"; 
    85         print "Expires: ", strftime ("%a, %d %b %Y %H:%M:%S GMT", gmtime(time+($period{$scale}-($time%$period{$scale})))), "\n"; 
    86         print "Last-Modified: $slast_modified\n"; 
    87         print "\n"; 
    88         exit 0; 
     87    # If a "Cache-Control: no-cache" header gets send, we regenerate the image in every case: 
     88    my $no_cache = defined($ENV{HTTP_CACHE_CONTROL}) && $ENV{HTTP_CACHE_CONTROL} =~ /no-cache/i; 
     89 
     90    if ($no_cache || ! &graph_usable ($filename, $time)) 
     91    { 
     92        my $ret = (&draw_graph ($host, $serv, $TIMES{$scale}) || "Unknown error"); 
     93        if (! -f $filename) 
     94        { 
     95        ::logger ("Warning: Could not draw graph \"$host-$serv-$scale.png\": $ret"); 
     96        print "Status: 500\n"; 
     97        print "Content-Type: image/png\n"; 
     98        print "\n"; 
     99        next; 
     100        } 
    89101    } 
    90 } 
    91102 
    92 if (! &graph_usable ($filename, $time)) 
    93 
    94     my $ret = (&draw_graph ($host, $serv, $TIMES{$scale}) || "Unknown error"); 
    95     if (! -f $filename) 
     103    my @stats = stat ($filename); 
     104    my $last_modified = strftime ("%a, %d %b %Y %H:%M:%S %Z", localtime ($stats[9])); 
     105    # "Expires" has to use last modified time as base: 
     106    my $expires = strftime ("%a, %d %b %Y %H:%M:%S GMT", gmtime($stats[9]+($period{$scale}-($stats[9]%$period{$scale})))); 
     107 
     108    # Check for If-Modified-Since and send 304 if not changed: 
     109    if (defined $ENV{HTTP_IF_MODIFIED_SINCE} and 
     110        !&modified ($ENV{HTTP_IF_MODIFIED_SINCE}, $stats[9]-1)) 
    96111    { 
    97         ::logger ("Warning: Could not draw graph \"$host-$serv-$scale.png\": $ret"); 
    98         print "Status: 500\n"; 
    99         print "Content-Type: image/png\n"; 
    100         print "\n"; 
    101         exit 0; 
     112        print "Status: 304\n"; 
     113        print "Content-Type: image/png\n"; 
     114        print "Expires: ", $expires, "\n"; 
     115        print "Last-Modified: $last_modified\n"; 
     116        print "\n"; 
     117        next; 
    102118    } 
    103 } 
    104119 
    105 my @stats = stat ($filename); 
    106 my $last_modified = strftime ("%a, %d %b %Y %H:%M:%S %Z", localtime ($stats[9])); 
     120    print "Content-Type: image/png\n"; 
     121    print "Expires: ", $expires, "\n"; 
     122    print "Last-Modified: $last_modified\n"; 
     123    print "\n"; 
    107124 
    108 print "Content-Type: image/png\n"; 
    109 print "Expires: ", strftime ("%a, %d %b %Y %H:%M:%S GMT", gmtime(time+($period{$scale}-($time%$period{$scale})))), "\n"; 
    110 print "Last-Modified: $last_modified\n"; 
    111 print "\n"; 
     125    # Try to police the number of concurrent rrdgraph instances.  The 
     126    # third value is the default maximum. 
    112127 
    113 # Try to police the number of concurrent rrdgraph instances.  The 
    114 # third value is the default maximum
     128    # Fox kindly submitted a patch to convert to SysV IPC semaphores. 
     129    # Lovely! (ticket #499)
    115130 
    116 # Fox kindly submitted a patch to convert to SysV IPC semaphores. 
    117 # Lovely! (ticket #499). 
     131    my $max_cgi_graph_jobs = &munin_get ($config, "max_cgi_graph_jobs" , 6, $dom); 
    118132 
    119 my $max_cgi_graph_jobs = &munin_get ($config, "max_cgi_graph_jobs" , 6, $dom); 
     133    my $opstring;  
    120134 
    121 my $opstring;  
     135    # Get semaphore handle 
     136    my $semid = semget($IPC_KEY, 0, 0 ); 
    122137 
    123 # Get semaphore handle 
    124 my $semid = semget($IPC_KEY, 0, 0 ); 
     138    if(!$semid) { 
     139        # Or create it if needed 
     140        $semid = semget($IPC_KEY, 1 , 0666 | &IPC_CREAT ) || 
     141            die "Cannot create semaphore: $!"; 
    125142 
    126 if(!$semid) { 
    127     # Or create it if needed 
    128     $semid = semget($IPC_KEY, 1 , 0666 | IPC_CREAT ) || 
    129         die "Creating semaphore: $!"; 
     143        # And initialize to max_cgi_graph_jobs 
     144        $opstring = pack("s!s!s!",0, $max_cgi_graph_jobs,0); 
     145        semop($semid,$opstring) || die "Cannot semop: $!"; 
     146    } 
    130147 
    131     # And initialize to max_cgi_graph_jobs 
    132     $opstring = pack("s!s!s!",0, $max_cgi_graph_jobs,0); 
    133     semop($semid,$opstring) || die "$!"; 
    134 
     148    # Decrement, or lock/hang/yield if already 0 
     149    $opstring = pack("s!s!s!",0, -1, 0); 
     150    semop($semid,$opstring); 
    135151 
    136 # Decrement, or lock/hang/yield if already 0 
    137 $opstring = pack("s!s!s!",0, -1, 0); 
    138 semop($semid,$opstring); 
     152    &graph ($filename); 
    139153 
    140 &graph ($filename); 
     154    # Increment (and release waiting processes) 
     155    $opstring = pack("s!s!s!",0, 1, 0); 
     156    semop($semid,$opstring); 
     157
     158# END FAST-CGI LOOP 
    141159 
    142 # Increment (and release waiting processes) 
    143 $opstring = pack("s!s!s!",0, 1, 0); 
    144 semop($semid,$opstring); 
    145160 
    146161sub graph { 
    147162    my $filename = shift; 
     
    214229        if (!$dom) 
    215230        { 
    216231                print STDERR "Warning: Request for graph without specifying domain. Bailing out.\n"; 
    217                 exit 1
     232                return 0
    218233        } 
    219234        if (!$host) 
    220235        { 
    221236                print STDERR "Warning: Request for graph without specifying host. Bailing out.\n"; 
    222                 exit 1
     237                return 0
    223238        } 
    224239        if (!$serv) 
    225240        { 
    226241                print STDERR "Warning: Request for graph without specifying service. Bailing out.\n"; 
    227                 exit 1
     242                return 0
    228243        } 
    229244 
    230245        if (!$scale) 
    231246        { 
    232247                print STDERR "Warning: Request for graph without specifying scale. Bailing out.\n"; 
    233                 exit 1
     248                return 0
    234249        } 
    235250        else 
    236251        { 
    237252                if (!defined $TIMES{$scale}) 
    238253                { 
    239254                        print STDERR "Warning: Weird scale setting \"$scale\". Bailing out.\n"; 
    240                         exit 1
     255                        return 0
    241256                } 
    242257        } 
     258        return 1; 
    243259} 
    244260 
    245261sub graph_usable { 
     
    248264 
    249265    if (-f $filename) { 
    250266        my @stats = stat (_); 
    251         my $expire = ($stats[9] - $time%$period{$scale}+$period{$scale})-$time; 
    252 #print STDERR "Expires in: $expire\n"; 
    253  
    254         if ($expire >= 0) { 
     267        # $stats[9] holds the "last update" time and this needs to be in the last update period: 
     268        if ($stats[9] > ($time - $time%$period{$scale})) { 
    255269#print STDERR "Skipping munin-graph-run for \"$filename\".\n"; 
    256270#print STDERR ("Graph unexpired for $scale. ($stats[9] , $time, ". ($time%$period{$scale}). ", ". ($time - $time%$period{$scale}). ").\n"); 
    257271            return 1;