* file named AUTHORS, in the root directory of this distribution.
*/
/*
- * $Id: amcleanupdisk.c,v 1.22 2006/07/25 18:27:57 martinea Exp $
+ * $Id: amcleanupdisk.c 7238 2007-07-06 20:03:37Z dustin $
*/
#include "amanda.h"
#include "infofile.h"
#include "server_util.h"
-sl_t *holding_list;
-char *datestamp;
+/* Utility funcitons */
-/* local functions */
-int main(int argc, char **argv);
-void check_holdingdisk(char *diskdir, char *datestamp);
-void check_disks(void);
+/* Call open_infofile() with the infofile from the configuration
+ */
+static void
+init_infofile(void)
+{
+ char *conf_infofile = config_dir_relative(getconf_str(CNF_INFOFILE));
+ if (open_infofile(conf_infofile) < 0) {
+ error(_("could not open info db \"%s\""), conf_infofile);
+ /*NOTREACHED*/
+ }
+ amfree(conf_infofile);
+}
+
+/* A callback for holding_cleanup to mark corrupt DLEs with force_no_bump
+ * for their next run.
+ *
+ * @param hostname: hostname of DLE
+ * @param disk: disk of DLE
+ */
+static void
+corrupt_dle(
+ char *hostname,
+ char *disk)
+{
+ info_t info;
+
+ dbprintf(_("Corrupted dump of DLE %s:%s found; setting force-no-bump.\n"),
+ hostname, disk);
+
+ get_info(hostname, disk, &info);
+ info.command &= ~FORCE_BUMP;
+ info.command |= FORCE_NO_BUMP;
+ if(put_info(hostname, disk, &info)) {
+ dbprintf(_("could not put info record for %s:%s: %s"),
+ hostname, disk, strerror(errno));
+ }
+}
int
main(
- int main_argc,
- char ** main_argv)
+ int argc,
+ char ** argv)
{
- struct passwd *pw;
- char *dumpuser;
- disklist_t diskq;
- char *conffile;
+ FILE *verbose_output = NULL;
+ char *cfg_opt = NULL;
char *conf_diskfile;
- char *conf_infofile;
+ disklist_t diskq;
+
+ /*
+ * Configure program for internationalization:
+ * 1) Only set the message locale for now.
+ * 2) Set textdomain for all amanda related programs to "amanda"
+ * We don't want to be forced to support dozens of message catalogs.
+ */
+ setlocale(LC_MESSAGES, "C");
+ textdomain("amanda");
safe_fd(-1, 0);
safe_cd();
dbopen(DBG_SUBDIR_SERVER);
- /* Don't die when child closes pipe */
- signal(SIGPIPE, SIG_IGN);
-
- if(main_argc != 2) {
- error("Usage: amcleanupdisk%s <confdir>", versionsuffix());
+ if(argc < 2) {
+ error(_("Usage: amcleanupdisk%s <config>"), versionsuffix());
/*NOTREACHED*/
}
- config_name = main_argv[1];
-
- config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
-
- conffile = stralloc2(config_dir, CONFFILE_NAME);
- if(read_conffile(conffile)) {
- error("errors processing config file \"%s\"", conffile);
- /*NOTREACHED*/
+ /* parse options */
+ if (argc >= 2 && strcmp(argv[1], "-v") == 0) {
+ verbose_output = stderr;
+ cfg_opt = argv[2];
+ } else {
+ cfg_opt = argv[1];
}
- amfree(conffile);
- dbrename(config_name, DBG_SUBDIR_SERVER);
+ config_init(CONFIG_INIT_EXPLICIT_NAME,
+ cfg_opt);
- conf_diskfile = getconf_str(CNF_DISKFILE);
- if (*conf_diskfile == '/') {
- conf_diskfile = stralloc(conf_diskfile);
- } else {
- conf_diskfile = stralloc2(config_dir, conf_diskfile);
- }
- if (read_diskfile(conf_diskfile, &diskq) < 0) {
- error("could not load disklist %s", conf_diskfile);
- /*NOTREACHED*/
- }
+ conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
+ read_diskfile(conf_diskfile, &diskq);
+ /* diskq also ends up in a global, used by holding_cleanup */
amfree(conf_diskfile);
- conf_infofile = getconf_str(CNF_INFOFILE);
- if (*conf_infofile == '/') {
- conf_infofile = stralloc(conf_infofile);
- } else {
- conf_infofile = stralloc2(config_dir, conf_infofile);
- }
- if (open_infofile(conf_infofile) < 0) {
- error("could not open info db \"%s\"", conf_infofile);
- /*NOTREACHED*/
+ if (config_errors(NULL) >= CFGERR_WARNINGS) {
+ config_print_errors();
+ if (config_errors(NULL) >= CFGERR_ERRORS) {
+ g_critical(_("errors processing config file"));
+ }
}
- amfree(conf_infofile);
- datestamp = construct_datestamp(NULL);
+ check_running_as(RUNNING_AS_DUMPUSER);
- dumpuser = getconf_str(CNF_DUMPUSER);
- if((pw = getpwnam(dumpuser)) == NULL) {
- error("dumpuser %s not found in password file", dumpuser);
- /*NOTREACHED*/
- }
+ dbrename(get_config_name(), DBG_SUBDIR_SERVER);
- if(pw->pw_uid != getuid()) {
- error("must run amcleanupdisk as user %s", dumpuser);
- /*NOTREACHED*/
- }
-
- holding_list = pick_all_datestamp(1);
+ init_infofile();
- check_disks();
+ /* actually perform the cleanup */
+ holding_cleanup(corrupt_dle, verbose_output);
close_infofile();
-
- free_sl(holding_list);
- holding_list = NULL;
- amfree(config_dir);
return 0;
}
-
-void
-check_holdingdisk(
- char * diskdir,
- char * datestamp)
-{
- DIR *workdir;
- struct dirent *entry;
- char *dirname = NULL;
- char *tmpname = NULL;
- char *destname = NULL;
- char *hostname = NULL;
- char *diskname = NULL;
- disk_t *dp;
- filetype_t filetype;
- info_t info;
- int level;
- size_t dl, l;
-
- dirname = vstralloc(diskdir, "/", datestamp, NULL);
- dl = strlen(dirname);
-
- if((workdir = opendir(dirname)) == NULL) {
- amfree(dirname);
- return;
- }
-
- while((entry = readdir(workdir)) != NULL) {
- if(is_dot_or_dotdot(entry->d_name)) {
- continue;
- }
-
- if((l = strlen(entry->d_name)) < 7 ) {
- continue;
- }
-
- if(strncmp(&entry->d_name[l-4],".tmp",4) != 0) {
- continue;
- }
-
- tmpname = newvstralloc(tmpname,
- dirname, "/", entry->d_name,
- NULL);
-
- destname = newstralloc(destname, tmpname);
- destname[dl + 1 + l - 4] = '\0';
-
- amfree(hostname);
- amfree(diskname);
- filetype = get_amanda_names(tmpname, &hostname, &diskname, &level);
- amfree(tmpname);
- if(filetype != F_DUMPFILE) {
- continue;
- }
-
- dp = lookup_disk(hostname, diskname);
-
- if (dp == NULL) {
- continue;
- }
-
- if(level < 0 || level > 9) {
- continue;
- }
-
- if(rename_tmp_holding(destname, 0)) {
- get_info(dp->host->hostname, dp->name, &info);
- info.command &= ~FORCE_BUMP;
- info.command |= FORCE_NO_BUMP;
- if(put_info(dp->host->hostname, dp->name, &info)) {
- error("could not put info record for %s:%s: %s",
- dp->host->hostname, dp->name, strerror(errno));
- /*NOTREACHED*/
- }
- } else {
- fprintf(stderr,"rename_tmp_holding(%s) failed\n", destname);
- }
- }
- closedir(workdir);
-
- /* try to zap the potentially empty working dir */
- /* ignore any errors -- it either works or it doesn't */
- (void) rmdir(dirname);
-
- amfree(diskname);
- amfree(hostname);
- amfree(destname);
- amfree(dirname);
-}
-
-
-void
-check_disks(void)
-{
- holdingdisk_t *hdisk;
- sle_t *dir;
-
- for(dir = holding_list->first; dir !=NULL; dir = dir->next) {
- for(hdisk = getconf_holdingdisks(); hdisk != NULL; hdisk = hdisk->next)
- check_holdingdisk(holdingdisk_get_diskdir(hdisk), dir->name);
- }
-}