[libvirt] [PATCH v2 01/13] util: add APIs for reading/writing from/to rotating files

John Ferlan jferlan at redhat.com
Wed Nov 18 13:46:43 UTC 2015



On 11/12/2015 12:18 PM, Daniel P. Berrange wrote:
> Add virRotatingFileReader and virRotatingFileWriter objects
> which allow reading & writing from/to files with automation
> rotation to N backup files when a size limit is reached. This
> is useful for guest logging when a guaranteed finite size
> limit is required. Use of external tools like logrotate is
> inadequate since it leaves the possibility for guest to DOS
> the host in between invokations of logrotate.
> 
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
>  po/POTFILES.in              |   1 +
>  src/Makefile.am             |   1 +
>  src/libvirt_private.syms    |  13 +
>  src/util/virrotatingfile.c  | 608 ++++++++++++++++++++++++++++++++++++++
>  src/util/virrotatingfile.h  |  62 ++++
>  tests/Makefile.am           |   6 +
>  tests/virrotatingfiletest.c | 698 ++++++++++++++++++++++++++++++++++++++++++++
>  7 files changed, 1389 insertions(+)
>  create mode 100644 src/util/virrotatingfile.c
>  create mode 100644 src/util/virrotatingfile.h
>  create mode 100644 tests/virrotatingfiletest.c
> 

[...]

> --- /dev/null
> +++ b/src/util/virrotatingfile.c
> @@ -0,0 +1,608 @@

In the grand scheme of things a nit - lately there seems to be an effort
to use two lines for functions, such as:

[static] int
virFunctionName(param1Type param1,
                param2Type param2)

This module has some that are and some that aren't.  I don't have heart
break one way or another, but someone may ;-)

> +/*
> + * virrotatingfile.c: file I/O with size rotation
> + *
> + * Copyright (C) 2015 Red Hat, Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library 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
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library.  If not, see
> + * <http://www.gnu.org/licenses/>.
> + *
> + */
> +

[...]

> +
> +
> +static virRotatingFileReaderEntryPtr
> +virRotatingFileReaderEntryNew(const char *path)
> +{
> +    virRotatingFileReaderEntryPtr entry;
> +    struct stat sb;
> +
> +    VIR_DEBUG("Opening %s", path);
> +
> +    if (VIR_ALLOC(entry) < 0)
> +        return NULL;
> +
> +    if (VIR_STRDUP(entry->path, path) < 0)
> +        goto error;

Should the open occur first; otherwise, entry->fd == 0 and the *Free
routine will VIR_FORCE_CLOSE(0);

> +
> +    if ((entry->fd = open(path, O_RDONLY)) < 0) {
> +        if (errno != ENOENT) {
> +            virReportSystemError(errno,
> +                                 _("Unable to open file: %s"), path);
> +            goto error;
> +        }
> +    }
> +
> +    if (entry->fd != -1) {
> +        if (fstat(entry->fd, &sb) < 0) {
> +            virReportSystemError(errno,
> +                                 _("Unable to determine current file inode: %s"),
> +                                 path);
> +            goto error;
> +        }
> +
> +        entry->inode = sb.st_ino;
> +    }
> +
> +    return entry;
> +
> + error:
> +    virRotatingFileReaderEntryFree(entry);
> +    return NULL;
> +}
> +

[...]

> +/**
> + * virRotatingFileWriterNew
> + * @path: the base path for files
> + * @maxlen: the maximum number of bytes to write before rollover
> + * @maxbackup: number of backup files to keep when rolloing over

rolling over

Although I don't see it being documented/used later in/for some config
file (and the max value I see used in code is 2)... Should there be some
sort of "sanity check" that maxbackup doesn't exceed some number - only
so many files can be open per process, right?  Then of course there's
the silly test of someone passing -1...

Also, as a config value it seems if someone changes the maxbackup value
(higher to lower), then some algorithms may miss files... If then going
from lower to higher, then files that may not have been deleted might be
found.

ACK -

John
> + * @truncate: whether to truncate the current files when opening
> + * @mode: the file mode to use for creating new files
> + *
> + * Create a new object for writing data to a file with
> + * automatic rollover. If @maxbackup is zero, no backup
> + * files will be created. The primary file will just get
> + * truncated and reopened.
> + *
> + * The files will never exceed @maxlen bytes in size,
> + * but may be rolled over before they reach this size
> + * in order to avoid splitting lines
> + */
> +virRotatingFileWriterPtr virRotatingFileWriterNew(const char *path,
> +                                                  off_t maxlen,
> +                                                  size_t maxbackup,
> +                                                  bool truncate,
> +                                                  mode_t mode)
> +{
> +    virRotatingFileWriterPtr file;
> +
> +    if (VIR_ALLOC(file) < 0)
> +        goto error;
> +
> +    if (VIR_STRDUP(file->basepath, path) < 0)
> +        goto error;
> +
> +    file->mode = mode;
> +    file->maxbackup = maxbackup;
> +    file->maxlen = maxlen;
> +
> +    if (truncate &&
> +        virRotatingFileWriterDelete(file) < 0)
> +        goto error;
> +
> +    if (!(file->entry = virRotatingFileWriterEntryNew(file->basepath,
> +                                                      mode)))
> +        goto error;
> +
> +    return file;
> +
> + error:
> +    virRotatingFileWriterFree(file);
> +    return NULL;
> +}
> +
> +




More information about the libvir-list mailing list