rotater.c 13.7 KB
Newer Older
Hardy Simpson's avatar
Hardy Simpson committed
1
/*
Hardy Simpson's avatar
Hardy Simpson committed
2
 * This file is part of the zlog Library.
Hardy Simpson's avatar
Hardy Simpson committed
3
 *
Hardy Simpson's avatar
Hardy Simpson committed
4
 * Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
Hardy Simpson's avatar
Hardy Simpson committed
5
 *
6
 * Licensed under the LGPL v2.1, see the file COPYING in base directory.
Hardy Simpson's avatar
Hardy Simpson committed
7 8
 */

Hardy Simpson's avatar
Hardy Simpson committed
9 10 11 12 13 14 15 16 17 18 19 20 21
#include <string.h>
#include <glob.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>

#include "zc_defs.h"
Hardy Simpson's avatar
Hardy Simpson committed
22
#include "rotater.h"
Hardy Simpson's avatar
Hardy Simpson committed
23

24 25 26 27 28 29 30 31
#define ROLLING  1     /* aa.02->aa.03, aa.01->aa.02, aa->aa.01 */
#define SEQUENCE 2     /* aa->aa.03 */

typedef struct {
	int index;
	char path[MAXLEN_PATH + 1];
} zlog_file_t;

32
void zlog_rotater_profile(zlog_rotater_t * a_rotater, int flag)
Hardy Simpson's avatar
Hardy Simpson committed
33
{
34
	zc_assert(a_rotater,);
35
	zc_profile(flag, "--rotater[%p][%p,%s,%d][%s,%s,%s,%ld,%ld,%d,%d,%d]--",
36
		a_rotater,
37

38 39
		&(a_rotater->lock_mutex),
		a_rotater->lock_file,
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
		a_rotater->lock_fd,

		a_rotater->base_path,
		a_rotater->archive_path,
		a_rotater->glob_path,
		(long)a_rotater->num_start_len,
		(long)a_rotater->num_end_len,
		a_rotater->num_width,
		a_rotater->mv_type,
		a_rotater->max_count
		);
	if (a_rotater->files) {
		int i;
		zlog_file_t *a_file;
		zc_arraylist_foreach(a_rotater->files, i, a_file) {
			zc_profile(flag, "[%s,%d]->", a_file->path, a_file->index);
		}
	}
Hardy Simpson's avatar
Hardy Simpson committed
58 59 60 61
	return;
}

/*******************************************************************************/
62
void zlog_rotater_del(zlog_rotater_t *a_rotater)
Hardy Simpson's avatar
Hardy Simpson committed
63
{
64
	zc_assert(a_rotater,);
Hardy Simpson's avatar
Hardy Simpson committed
65

66
	if (a_rotater->lock_fd) {
Hardy Simpson's avatar
Hardy Simpson committed
67
		if (close(a_rotater->lock_fd)) {
Hardy Simpson's avatar
Hardy Simpson committed
68 69 70 71
			zc_error("close fail, errno[%d]", errno);
		}
	}

Hardy Simpson's avatar
Hardy Simpson committed
72
	if (pthread_mutex_destroy(&(a_rotater->lock_mutex))) {
Hardy Simpson's avatar
Hardy Simpson committed
73 74 75
		zc_error("pthread_mutex_destroy fail, errno[%d]", errno);
	}

76 77
	free(a_rotater);
	zc_debug("zlog_rotater_del[%p]", a_rotater);
Hardy Simpson's avatar
Hardy Simpson committed
78 79 80 81 82 83
	return;
}

zlog_rotater_t *zlog_rotater_new(char *lock_file)
{
	int fd = 0;
84
	zlog_rotater_t *a_rotater;
Hardy Simpson's avatar
Hardy Simpson committed
85

86 87 88 89
	zc_assert(lock_file, NULL);

	a_rotater = calloc(1, sizeof(zlog_rotater_t));
	if (!a_rotater) {
Hardy Simpson's avatar
Hardy Simpson committed
90 91 92 93
		zc_error("calloc fail, errno[%d]", errno);
		return NULL;
	}

Hardy Simpson's avatar
Hardy Simpson committed
94
	if (pthread_mutex_init(&(a_rotater->lock_mutex), NULL)) {
Hardy Simpson's avatar
Hardy Simpson committed
95
		zc_error("pthread_mutex_init fail, errno[%d]", errno);
96
		free(a_rotater);
Hardy Simpson's avatar
Hardy Simpson committed
97 98 99 100 101 102 103 104 105 106 107 108
		return NULL;
	}

	/* depends on umask of the user here
	 * if user A create /tmp/zlog.lock 0600
	 * user B is unable to read /tmp/zlog.lock
	 * B has to choose another lock file except /tmp/zlog.lock
	 */
	fd = open(lock_file, O_RDWR | O_CREAT,
		  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
	if (fd < 0) {
		zc_error("open file[%s] fail, errno[%d]", lock_file, errno);
Hardy Simpson's avatar
Hardy Simpson committed
109
		goto err;
Hardy Simpson's avatar
Hardy Simpson committed
110
	}
111

112 113
	a_rotater->lock_fd = fd;
	a_rotater->lock_file = lock_file;
Hardy Simpson's avatar
Hardy Simpson committed
114

115
	//zlog_rotater_profile(a_rotater, ZC_DEBUG);
Hardy Simpson's avatar
Hardy Simpson committed
116 117 118 119
	return a_rotater;
err:
	zlog_rotater_del(a_rotater);
	return NULL;
Hardy Simpson's avatar
Hardy Simpson committed
120
}
121

Hardy Simpson's avatar
Hardy Simpson committed
122 123
/*******************************************************************************/

124
static void zlog_file_del(zlog_file_t * a_file)
Hardy Simpson's avatar
Hardy Simpson committed
125
{
126
	zc_debug("del onefile[%p]", a_file);
Hardy Simpson's avatar
Hardy Simpson committed
127 128
	zc_debug("a_file->path[%s]", a_file->path);
	free(a_file);
Hardy Simpson's avatar
Hardy Simpson committed
129 130
}

131
static zlog_file_t *zlog_file_check_new(zlog_rotater_t * a_rotater, const char *path)
132 133
{
	int nwrite;
134 135
	int nread;
	zlog_file_t *a_file;
136

137 138 139
	/* base_path will not be in list */
	if (STRCMP(a_rotater->base_path, ==, path)) {
		return NULL;
140 141
	}

142 143 144
	/* omit dirs */
	if ((path)[strlen(path) - 1] == '/') {
		return NULL;
145 146 147 148 149 150 151 152 153 154 155 156 157 158
	}

	a_file = calloc(1, sizeof(zlog_file_t));
	if (!a_file) {
		zc_error("calloc fail, errno[%d]", errno);
		return NULL;
	}

	nwrite = snprintf(a_file->path, sizeof(a_file->path), "%s", path);
	if (nwrite < 0 || nwrite >= sizeof(a_file->path)) {
		zc_error("snprintf fail or overflow, nwrite=[%d], errno[%d]", nwrite, errno);
		goto err;
	}

159
	nread = 0;
160
	sscanf(a_file->path + a_rotater->num_start_len, "%d%n", &(a_file->index), &(nread));
161 162 163 164 165 166 167 168 169 170 171 172 173 174

	if (a_rotater->num_width != 0) {
		if (nread < a_rotater->num_width) {
			zc_warn("aa.1.log is not expect, need aa.01.log");
			goto err;
		}
	} /* else all file is ok */

	return a_file;
err:
	free(a_file);
	return NULL;
}

Hardy Simpson's avatar
Hardy Simpson committed
175

176
static int zlog_file_cmp(zlog_file_t * a_file_1, zlog_file_t * a_file_2)
Hardy Simpson's avatar
Hardy Simpson committed
177
{
178
	return (a_file_1->index > a_file_2->index);
Hardy Simpson's avatar
Hardy Simpson committed
179 180
}

181
static int zlog_rotater_add_archive_files(zlog_rotater_t * a_rotater)
Hardy Simpson's avatar
Hardy Simpson committed
182
{
183
	int rc = 0;
184 185 186
	glob_t glob_buf;
	size_t pathc;
	char **pathv;
187
	zlog_file_t *a_file;
Hardy Simpson's avatar
Hardy Simpson committed
188

189 190
	a_rotater->files = zc_arraylist_new((zc_arraylist_del_fn)zlog_file_del);
	if (!a_rotater->files) {
191 192 193
		zc_error("zc_arraylist_new fail");
		return -1;
	}
194

195 196
	/* scan file which is aa.*.log and aa */
	rc = glob(a_rotater->glob_path, GLOB_ERR | GLOB_MARK | GLOB_NOSORT, NULL, &glob_buf);
197 198 199
	if (rc == GLOB_NOMATCH) {
		goto exit;
	} else if (rc) {
200 201 202
		zc_error("glob err, rc=[%d], errno[%d]", rc, errno);
		return -1;
	}
Hardy Simpson's avatar
Hardy Simpson committed
203

204 205 206 207 208
	pathv = glob_buf.gl_pathv;
	pathc = glob_buf.gl_pathc;

	/* check and find match aa.[0-9]*.log, depend on num_width */
	for (; pathc-- > 0; pathv++) {
209
		a_file = zlog_file_check_new(a_rotater, *pathv);
210 211 212 213 214
		if (!a_file) {
			zc_warn("not the expect pattern file");
			continue;
		}

215 216 217
		/* file in list aa.00, aa.01, aa.02... */
		rc = zc_arraylist_sortadd(a_rotater->files,
					(zc_arraylist_cmp_fn)zlog_file_cmp, a_file);
218 219 220
		if (rc) {
			zc_error("zc_arraylist_sortadd fail");
			goto err;
Hardy Simpson's avatar
Hardy Simpson committed
221 222 223
		}
	}

224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
exit:
	globfree(&glob_buf);
	return 0;
err:
	globfree(&glob_buf);
	return -1;
}

static int zlog_rotater_seq_files(zlog_rotater_t * a_rotater)
{
	int rc = 0;
	int nwrite = 0;
	int i, j;
	zlog_file_t *a_file;
	char new_path[MAXLEN_PATH + 1];

	zc_arraylist_foreach(a_rotater->files, i, a_file) {
		if (a_rotater->max_count > 0 
			&& i < zc_arraylist_len(a_rotater->files) - a_rotater->max_count) {
			/* unlink aa.0 aa.1 .. aa.(n-c) */
			rc = unlink(a_file->path);
			if (rc) {
				zc_error("unlink[%s] fail, errno[%d]",a_file->path , errno);
				return -1;
			}
			continue;
		}
	}

	if (zc_arraylist_len(a_rotater->files) > 0) { /* list is not empty */
		a_file = zc_arraylist_get(a_rotater->files, zc_arraylist_len(a_rotater->files)-1);
		if (!a_file) {
			zc_error("zc_arraylist_get fail");
			return -1;
		}

		j = zc_max(zc_arraylist_len(a_rotater->files)-1, a_file->index) + 1;
	} else {
		j = 0;
	}

	/* do the base_path mv  */
	memset(new_path, 0x00, sizeof(new_path));
	nwrite = snprintf(new_path, sizeof(new_path), "%.*s%0*d%s",
		(int) a_rotater->num_start_len, a_rotater->glob_path, 
		a_rotater->num_width, j,
		a_rotater->glob_path + a_rotater->num_end_len);
	if (nwrite < 0 || nwrite >= sizeof(new_path)) {
		zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
		return -1;
	}

	if (rename(a_rotater->base_path, new_path)) {
		zc_error("rename[%s]->[%s] fail, errno[%d]", a_rotater->base_path, new_path, errno);
		return -1;
	}

	return 0;
}


static int zlog_rotater_roll_files(zlog_rotater_t * a_rotater)
{
	int i;
	int rc = 0;
	int nwrite;
	char new_path[MAXLEN_PATH + 1];
	zlog_file_t *a_file;

	/* now in the list, aa.0 aa.1 aa.2 aa.02... */
294
	for (i = zc_arraylist_len(a_rotater->files) - 1; i > -1; i--) {
295
		a_file = zc_arraylist_get(a_rotater->files, i);
296 297
		if (!a_file) {
			zc_error("zc_arraylist_get fail");
298
			return -1;
Hardy Simpson's avatar
Hardy Simpson committed
299
		}
300 301 302 303 304

		if (a_rotater->max_count > 0 && i >= a_rotater->max_count - 1) {
			/* remove file.3 >= 3*/
			rc = unlink(a_file->path);
			if (rc) {
305 306
				zc_error("unlink[%s] fail, errno[%d]",a_file->path , errno);
				return -1;
307 308 309 310
			}
			continue;
		}

311
		/* begin rename aa.01.log -> aa.02.log , using i, as index in list maybe repeat */
312
		memset(new_path, 0x00, sizeof(new_path));
313 314 315 316 317 318 319
		nwrite = snprintf(new_path, sizeof(new_path), "%.*s%0*d%s",
			(int) a_rotater->num_start_len, a_rotater->glob_path, 
			a_rotater->num_width, i + 1,
			a_rotater->glob_path + a_rotater->num_end_len);
		if (nwrite < 0 || nwrite >= sizeof(new_path)) {
			zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
			return -1;
320 321
		}

322 323 324
		if (rename(a_file->path, new_path)) {
			zc_error("rename[%s]->[%s] fail, errno[%d]", a_file->path, new_path, errno);
			return -1;
Hardy Simpson's avatar
Hardy Simpson committed
325 326 327
		}
	}

328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
	/* do the base_path mv  */
	memset(new_path, 0x00, sizeof(new_path));
	nwrite = snprintf(new_path, sizeof(new_path), "%.*s%0*d%s",
		(int) a_rotater->num_start_len, a_rotater->glob_path, 
		a_rotater->num_width, 0,
		a_rotater->glob_path + a_rotater->num_end_len);
	if (nwrite < 0 || nwrite >= sizeof(new_path)) {
		zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
		return -1;
	}

	if (rename(a_rotater->base_path, new_path)) {
		zc_error("rename[%s]->[%s] fail, errno[%d]", a_rotater->base_path, new_path, errno);
		return -1;
	}

Hardy Simpson's avatar
Hardy Simpson committed
344 345 346
	return 0;
}

347 348

static int zlog_rotater_parse_archive_path(zlog_rotater_t * a_rotater)
Hardy Simpson's avatar
Hardy Simpson committed
349
{
350 351 352 353 354 355
	int nwrite;
	int nread;
	char *p;
	size_t len;

	/* no archive path is set */
356
	if (a_rotater->archive_path[0] == '\0') {
357 358 359
		nwrite = snprintf(a_rotater->glob_path, sizeof(a_rotater->glob_path),
					"%s.*", a_rotater->base_path);
		if (nwrite < 0 || nwrite > sizeof(a_rotater->glob_path)) {
360
			zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
361 362
			return -1;
		}
Hardy Simpson's avatar
Hardy Simpson committed
363

364 365
		a_rotater->mv_type = ROLLING;
		a_rotater->num_width = 0;
366 367
		a_rotater->num_start_len = strlen(a_rotater->base_path) + 1;
		a_rotater->num_end_len = strlen(a_rotater->base_path) + 2;
368
		return 0;
369
	} else {
Hardy Simpson's avatar
Hardy Simpson committed
370

371 372 373 374 375 376
		/* find the 1st # */
		p = strchr(a_rotater->archive_path, '#');
		if (!p) {
			zc_error("no # in archive_path[%s]", a_rotater->archive_path);
			return -1;
		}
377

378
		nread = 0;
379 380 381 382 383 384 385 386 387 388
		sscanf(p, "#%d%n", &(a_rotater->num_width), &nread);
		if (nread == 0) nread = 1;
		if (*(p+nread) == 'r') {
			a_rotater->mv_type = ROLLING;
		} else if (*(p+nread) == 's') {
			a_rotater->mv_type = SEQUENCE;
		} else {
			zc_error("#r or #s not found");
			return -1;
		}
Hardy Simpson's avatar
Hardy Simpson committed
389

390 391 392 393 394 395 396
		/* copy and substitue #i to * in glob_path*/
		len = p - a_rotater->archive_path;
		if (len > sizeof(a_rotater->glob_path) - 1) {
			zc_error("sizeof glob_path not enough,len[%ld]", (long) len);
			return -1;
		}
		memcpy(a_rotater->glob_path, a_rotater->archive_path, len);
Hardy Simpson's avatar
Hardy Simpson committed
397

398 399 400 401 402 403
		nwrite = snprintf(a_rotater->glob_path + len, sizeof(a_rotater->glob_path) - len,
				"*%s", p + nread + 1);
		if (nwrite < 0 || nwrite > sizeof(a_rotater->glob_path) - len) {
			zc_error("nwirte[%d], overflow or errno[%d]", nwrite, errno);
			return -1;
		}
404

405 406
		a_rotater->num_start_len = len;
		a_rotater->num_end_len = len + 1;
407 408 409
	}
	
	return 0;
Hardy Simpson's avatar
Hardy Simpson committed
410 411
}

412 413 414 415 416 417 418 419 420 421 422
static void zlog_rotater_clean(zlog_rotater_t *a_rotater)
{
	a_rotater->base_path = NULL;
	a_rotater->archive_path = NULL;
	a_rotater->max_count = 0;
	a_rotater->mv_type = 0;
	a_rotater->num_width = 0;
	a_rotater->num_start_len = 0;
	a_rotater->num_end_len = 0;
	memset(a_rotater->glob_path, 0x00, sizeof(a_rotater->glob_path));

423 424
	if (a_rotater->files) zc_arraylist_del(a_rotater->files);
	a_rotater->files = NULL;
425
}
Hardy Simpson's avatar
Hardy Simpson committed
426

427 428
static int zlog_rotater_lsmv(zlog_rotater_t *a_rotater, 
		char *base_path, char *archive_path, int archive_max_count)
Hardy Simpson's avatar
Hardy Simpson committed
429
{
430
	int rc = 0;
Hardy Simpson's avatar
Hardy Simpson committed
431

432 433
	a_rotater->base_path = base_path;
	a_rotater->archive_path = archive_path;
434
	a_rotater->max_count = archive_max_count;
435 436 437 438
	rc = zlog_rotater_parse_archive_path(a_rotater);
	if (rc) {
		zc_error("zlog_rotater_parse_archive_path fail");
		goto err;
Hardy Simpson's avatar
Hardy Simpson committed
439 440
	}

441 442 443 444 445 446
	rc = zlog_rotater_add_archive_files(a_rotater);
	if (rc) {
		zc_error("zlog_rotater_add_archive_files fail");
		goto err;
	}

447 448 449 450 451 452
	if (a_rotater->mv_type == ROLLING) {
		rc = zlog_rotater_roll_files(a_rotater);
		if (rc) {
			zc_error("zlog_rotater_roll_files fail");
			goto err;
		}
453 454
	} else if (a_rotater->mv_type == SEQUENCE) {
		rc = zlog_rotater_seq_files(a_rotater);
455
		if (rc) {
456
			zc_error("zlog_rotater_seq_files fail");
457 458
			goto err;
		}
Hardy Simpson's avatar
Hardy Simpson committed
459 460
	}

461
	zlog_rotater_clean(a_rotater);
Hardy Simpson's avatar
Hardy Simpson committed
462
	return 0;
463 464 465
err:
	zlog_rotater_clean(a_rotater);
	return -1;
Hardy Simpson's avatar
Hardy Simpson committed
466
}
467 468 469 470
/*******************************************************************************/

static int zlog_rotater_trylock(zlog_rotater_t *a_rotater)
{
471
	int rc;
472 473 474 475 476 477 478
	struct flock fl;

	fl.l_type = F_WRLCK;
	fl.l_start = 0;
	fl.l_whence = SEEK_SET;
	fl.l_len = 0;

479 480 481 482 483 484
	rc = pthread_mutex_trylock(&(a_rotater->lock_mutex));
	if (rc == EBUSY) {
		zc_warn("pthread_mutex_trylock fail, as lock_mutex is locked by other threads");
		return -1;
	} else if (rc != 0) {
		zc_error("pthread_mutex_trylock fail, rc[%d]", rc);
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
		return -1;
	}

	if (fcntl(a_rotater->lock_fd, F_SETLK, &fl)) {
		if (errno == EAGAIN || errno == EACCES) {
			/* lock by other process, that's right, go on */
			/* EAGAIN on linux */
			/* EACCES on AIX */
			zc_warn("fcntl lock fail, as file is lock by other process");
		} else {
			zc_error("lock fd[%d] fail, errno[%d]", a_rotater->lock_fd, errno);
		}
		if (pthread_mutex_unlock(&(a_rotater->lock_mutex))) {
			zc_error("pthread_mutex_unlock fail, errno[%d]", errno);
		}
		return -1;
	}

	return 0;
}

static int zlog_rotater_unlock(zlog_rotater_t *a_rotater)
Hardy Simpson's avatar
Hardy Simpson committed
507 508
{
	int rc = 0;
509
	struct flock fl;
Hardy Simpson's avatar
Hardy Simpson committed
510

511 512 513 514
	fl.l_type = F_UNLCK;
	fl.l_start = 0;
	fl.l_whence = SEEK_SET;
	fl.l_len = 0;
Hardy Simpson's avatar
Hardy Simpson committed
515

516 517 518
	if (fcntl(a_rotater->lock_fd, F_SETLK, &fl)) {
		rc = -1;
		zc_error("unlock fd[%s] fail, errno[%d]", a_rotater->lock_fd, errno);
Hardy Simpson's avatar
Hardy Simpson committed
519 520
	}

521 522 523
	if (pthread_mutex_unlock(&(a_rotater->lock_mutex))) {
		rc = -1;
		zc_error("pthread_mutext_unlock fail, errno[%d]", errno);
Hardy Simpson's avatar
Hardy Simpson committed
524 525
	}

526 527 528 529
	return rc;
}

int zlog_rotater_rotate(zlog_rotater_t *a_rotater,
530
		char *base_path, size_t msg_len,
531
		char *archive_path, long archive_max_size, int archive_max_count)
532 533 534 535 536
{
	int rc = 0;
	struct zlog_stat info;

	zc_assert(base_path, -1);
Hardy Simpson's avatar
Hardy Simpson committed
537 538

	if (zlog_rotater_trylock(a_rotater)) {
539
		zc_warn("zlog_rotater_trylock fail, maybe lock by other process or threads");
Hardy Simpson's avatar
Hardy Simpson committed
540 541 542
		return 0;
	}

543
	if (stat(base_path, &info)) {
Hardy Simpson's avatar
Hardy Simpson committed
544
		rc = -1;
545
		zc_error("stat [%s] fail, errno[%d]", base_path, errno);
Hardy Simpson's avatar
Hardy Simpson committed
546
		goto exit;
Hardy Simpson's avatar
Hardy Simpson committed
547 548
	}

549
	if (info.st_size + msg_len <= archive_max_size) {
550 551 552
		/* file not so big,
		 * may alread rotate by oth process or thread,
		 * return */
Hardy Simpson's avatar
Hardy Simpson committed
553
		rc = 0;
Hardy Simpson's avatar
Hardy Simpson committed
554
		goto exit;
Hardy Simpson's avatar
Hardy Simpson committed
555 556 557
	}

	/* begin list and move files */
558
	rc = zlog_rotater_lsmv(a_rotater, base_path, archive_path, archive_max_count);
Hardy Simpson's avatar
Hardy Simpson committed
559
	if (rc) {
560 561 562 563
		zc_error("zlog_rotater_lsmv [%s] fail, return", base_path);
		rc = -1;
	} /* else if (rc == 0) */

564
	//zc_debug("zlog_rotater_file_ls_mv success");
565

Hardy Simpson's avatar
Hardy Simpson committed
566
exit:
Hardy Simpson's avatar
Hardy Simpson committed
567
	/* unlock file */
Hardy Simpson's avatar
Hardy Simpson committed
568
	if (zlog_rotater_unlock(a_rotater)) {
Hardy Simpson's avatar
Hardy Simpson committed
569
		zc_error("zlog_rotater_unlock fail");
Hardy Simpson's avatar
Hardy Simpson committed
570 571 572 573 574 575
	}

	return rc;
}

/*******************************************************************************/