]> git.sur5r.net Git - bacula/bacula/commitdiff
Verify cleanups + eliminate unwanted messages
authorKern Sibbald <kern@sibbald.com>
Sun, 1 Sep 2002 18:40:16 +0000 (18:40 +0000)
committerKern Sibbald <kern@sibbald.com>
Sun, 1 Sep 2002 18:40:16 +0000 (18:40 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@138 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/kernstodo
bacula/src/cats/sql.c
bacula/src/cats/sql_get.c
bacula/src/cats/sql_list.c
bacula/src/cats/sql_update.c
bacula/src/filed/backup.c
bacula/src/filed/verify.c
bacula/src/lib/message.c

index 45d0d40d57547d7ad0db5308f6605a07aaf69509..f0d423fca08284d0a95be028b19358fdf93ddfab 100644 (file)
@@ -28,6 +28,7 @@ From Chuck:
 --sd.conf password does not match dir.conf storage password
 =======
 
+- Write updated bootstrap after every Job.
 - Correct Warning: Volume name mismatch. Wanted test2 got test1
   when reading a tape and want the next one.
 - Create all pools when Director starts
index 2948c77d731bdd99a3e8bd7a41ca071fe4f25e80..3444062ad5608c16683c677ecb20f2cbd3aaa53b 100644 (file)
@@ -117,7 +117,6 @@ InsertDB(char *file, int line, B_DB *mdb, char *cmd)
       char ed1[30];
       m_msg(file, line, &mdb->errmsg, _("Insertion problem: affect_rows=%s\n"), 
         edit_uint64(mdb->num_rows, ed1));
-      j_msg(file, line, mdb->jcr, M_FATAL, 0, mdb->errmsg);  /* ***FIXME*** remove me */
       return 0;
    }
    mdb->changes++;
@@ -143,8 +142,6 @@ UpdateDB(char *file, int line, B_DB *mdb, char *cmd)
       char ed1[30];
       m_msg(file, line, &mdb->errmsg, _("Update problem: affect_rows=%s\n"), 
         edit_uint64(mdb->num_rows, ed1));
-      j_msg(file, line, mdb->jcr, M_ERROR, 0, mdb->errmsg);
-      j_msg(file, line, mdb->jcr, M_ERROR, 0, "%s\n", cmd);
       return 0;
    }
    mdb->changes++;
index 2f65ad1bd30b46c1e0e9c277ed914761908e6b49..83e6025ab66b24fd1d5b4f96c878af094a42f0de 100644 (file)
@@ -70,7 +70,7 @@ int db_get_file_attributes_record(B_DB *mdb, char *fname, FILE_DBR *fdbr)
 {
    int fnl, pnl;
    char *l, *p;
-   uint64_t id;
+   int stat;
    char file[MAXSTRING];
    char spath[MAXSTRING];
    char buf[MAXSTRING];
@@ -133,22 +133,28 @@ int db_get_file_attributes_record(B_DB *mdb, char *fname, FILE_DBR *fdbr)
 
    db_escape_string(buf, file, fnl);
    fdbr->FilenameId = db_get_filename_record(mdb, buf);
-   Dmsg2(100, "db_get_filename_record FilenameId=%d file=%s\n", fdbr->FilenameId, buf);
+   Dmsg2(100, "db_get_filename_record FilenameId=%u file=%s\n", fdbr->FilenameId, buf);
 
    db_escape_string(buf, spath, pnl);
    fdbr->PathId = db_get_path_record(mdb, buf);
-   Dmsg2(100, "db_get_path_record PathId=%d path=%s\n", fdbr->PathId, buf);
+   Dmsg2(100, "db_get_path_record PathId=%u path=%s\n", fdbr->PathId, buf);
 
-   id = db_get_file_record(mdb, fdbr);
+   stat = db_get_file_record(mdb, fdbr);
 
-   return id;
+   return stat;
 }
 
  
-
-/* Get a File record   
+/*
+ * Get a File record   
  * Returns: 0 on failure
  *         1 on success
+ *
+ *  DO NOT use Jmsg in this routine.
+ *
+ *  Note in this routine, we do not use Jmsg because it may be
+ *    called to get attributes of a non-existant file, which is
+ *    "normal" if a new file is found during Verify.
  */
 static
 int db_get_file_record(B_DB *mdb, FILE_DBR *fdbr)
@@ -158,10 +164,10 @@ int db_get_file_record(B_DB *mdb, FILE_DBR *fdbr)
 
    db_lock(mdb);
    Mmsg(&mdb->cmd, 
-"SELECT FileId, LStat, MD5 from File where File.JobId=%d and File.PathId=%d and \
-File.FilenameId=%d", fdbr->JobId, fdbr->PathId, fdbr->FilenameId);
+"SELECT FileId, LStat, MD5 from File where File.JobId=%u and File.PathId=%u and \
+File.FilenameId=%u", fdbr->JobId, fdbr->PathId, fdbr->FilenameId);
 
-   Dmsg3(050, "Get_file_record JobId=%d FilenameId=%d PathId=%d\n",
+   Dmsg3(050, "Get_file_record JobId=%u FilenameId=%u PathId=%u\n",
       fdbr->JobId, fdbr->FilenameId, fdbr->PathId);
       
    Dmsg1(100, "Query=%s\n", mdb->cmd);
@@ -171,18 +177,13 @@ File.FilenameId=%d", fdbr->JobId, fdbr->PathId, fdbr->FilenameId);
       mdb->num_rows = sql_num_rows(mdb);
       Dmsg1(050, "get_file_record num_rows=%d\n", (int)mdb->num_rows);
 
-      /* 
-       * Note, we can find more than one File record with the same
-       *  filename if the file is linked.   ????????
-       */
       if (mdb->num_rows > 1) {
-         Jmsg1(mdb->jcr, M_WARNING, 0, _("get_file_record want 1 got rows=%d\n"), mdb->num_rows);
-         Jmsg1(mdb->jcr, M_ERROR, 0, "%s", mdb->cmd);
+         Mmsg1(&mdb->errmsg, _("get_file_record want 1 got rows=%d\n"),
+           mdb->num_rows);
       }
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
-            Mmsg1(&mdb->errmsg, "Error fetching row: %s\n", sql_strerror(mdb));
-            Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
+            Mmsg1(&mdb->errmsg, _("Error fetching row: %s\n"), sql_strerror(mdb));
         } else {
            fdbr->FileId = (FileId_t)strtod(row[0], NULL);
            strncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat));
@@ -202,6 +203,8 @@ File.FilenameId=%d", fdbr->JobId, fdbr->PathId, fdbr->FilenameId);
 /* Get Filename record  
  * Returns: 0 on failure
  *         FilenameId on success
+ *
+ *   DO NOT use Jmsg in this routine (see notes for get_file_record)
  */
 static int db_get_filename_record(B_DB *mdb, char *fname) 
 {
@@ -221,18 +224,15 @@ static int db_get_filename_record(B_DB *mdb, char *fname)
 
       if (mdb->num_rows > 1) {
          Mmsg1(&mdb->errmsg, _("More than one Filename!: %d\n"), (int)(mdb->num_rows));
-         Jmsg(mdb->jcr, M_WARNING, 0, "%s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
-            Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
         } else {
            FilenameId = atoi(row[0]);
            if (FilenameId <= 0) {
                Mmsg2(&mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"),
                  mdb->cmd, FilenameId); 
-               Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
               FilenameId = 0;
            }
         }
@@ -246,6 +246,8 @@ static int db_get_filename_record(B_DB *mdb, char *fname)
 /* Get path record   
  * Returns: 0 on failure
  *         PathId on success
+ *
+ *   DO NOT use Jmsg in this routine (see notes for get_file_record)
  */
 static int db_get_path_record(B_DB *mdb, char *path)
 {
@@ -276,13 +278,11 @@ static int db_get_path_record(B_DB *mdb, char *path)
       } else if (mdb->num_rows == 1) {
         if ((row = sql_fetch_row(mdb)) == NULL) {
             Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
-            Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
         } else {
            PathId = atoi(row[0]);
            if (PathId <= 0) {
-               Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %d\n"),
+               Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %u\n"),
                  mdb->cmd, PathId); 
-               Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
               PathId = 0;
            } else {
               /* Cache path */
@@ -319,7 +319,7 @@ FROM Job WHERE Job='%s'", jr->Job);
     } else {
       Mmsg(&mdb->cmd, "SELECT VolSessionId, VolSessionTime, \
 PoolId, StartTime, EndTime, JobFiles, JobBytes, JobTDate, Job, JobStatus \
-FROM Job WHERE JobId=%d", jr->JobId);
+FROM Job WHERE JobId=%u", jr->JobId);
     }
 
    if (!QUERY_DB(mdb, mdb->cmd)) {
@@ -327,7 +327,7 @@ FROM Job WHERE JobId=%d", jr->JobId);
       return 0;                      /* failed */
    }
    if ((row = sql_fetch_row(mdb)) == NULL) {
-      Mmsg1(&mdb->errmsg, _("No Job found for JobId %d\n"), jr->JobId);
+      Mmsg1(&mdb->errmsg, _("No Job found for JobId %u\n"), jr->JobId);
       Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg);
       sql_free_result(mdb);
       db_unlock(mdb);
@@ -365,7 +365,7 @@ int db_get_job_volume_names(B_DB *mdb, uint32_t JobId, POOLMEM **VolumeNames)
 
    db_lock(mdb);
    Mmsg(&mdb->cmd, 
-"SELECT VolumeName FROM JobMedia,Media WHERE JobMedia.JobId=%d \
+"SELECT VolumeName FROM JobMedia,Media WHERE JobMedia.JobId=%u \
 AND JobMedia.MediaId=Media.MediaId", JobId);
 
    Dmsg1(130, "VolNam=%s\n", mdb->cmd);
index 72507d3e8146371ec3d53dbeea3dc75f5dfd6f75..560c181abd225e3bef72ec5f189d8671d4a5cfda 100644 (file)
@@ -98,7 +98,7 @@ db_list_media_records(B_DB *mdb, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void
 
    Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,MediaType,VolStatus,\
 VolBytes,LastWritten,VolRetention,Recycle,Slot \
-FROM Media WHERE Media.PoolId=%d ORDER BY MediaId", mdbr->PoolId);
+FROM Media WHERE Media.PoolId=%u ORDER BY MediaId", mdbr->PoolId);
 
    db_lock(mdb);
    if (!QUERY_DB(mdb, mdb->cmd)) {
@@ -116,7 +116,7 @@ void db_list_jobmedia_records(B_DB *mdb, uint32_t JobId, DB_LIST_HANDLER *sendit
 {
    if (JobId > 0) {                  /* do by JobId */
       Mmsg(&mdb->cmd, "SELECT JobId, Media.VolumeName, FirstIndex, LastIndex \
-FROM JobMedia, Media WHERE Media.MediaId=JobMedia.MediaId and JobMedia.JobId=%d", 
+FROM JobMedia, Media WHERE Media.MediaId=JobMedia.MediaId and JobMedia.JobId=%u", 
           JobId);
    } else {
       Mmsg(&mdb->cmd, "SELECT JobId, Media.VolumeName, FirstIndex, LastIndex \
@@ -152,7 +152,7 @@ db_list_job_records(B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, void *ctx)
 JobFiles,JobBytes,JobStatus FROM Job");
    } else {                          /* single record */
       Mmsg(&mdb->cmd, "SELECT JobId,Name,StartTime,Type,Level,\
-JobFiles,JobBytes,JobStatus FROM Job WHERE Job.JobId=%d", jr->JobId);
+JobFiles,JobBytes,JobStatus FROM Job WHERE Job.JobId=%u", jr->JobId);
    }
 
    db_lock(mdb);
@@ -212,7 +212,7 @@ db_list_files_for_job(B_DB *mdb, uint32_t jobid, DB_LIST_HANDLER *sendit, void *
 {
 
    Mmsg(&mdb->cmd, "SELECT Path.Path,Filename.Name FROM File,\
-Filename,Path WHERE File.JobId=%d and Filename.FilenameId=File.FilenameId \
+Filename,Path WHERE File.JobId=%u and Filename.FilenameId=File.FilenameId \
 and Path.PathId=File.PathId",
       jobid);
 
index 02dbf324bf541af414e67454376869e1376aa153..520c1b553a10faee2074be66eed5ebaf97f5ccb8 100644 (file)
@@ -60,7 +60,7 @@ db_add_MD5_to_file_record(B_DB *mdb, FileId_t FileId, char *MD5)
    int stat;
 
    db_lock(mdb);
-   Mmsg(&mdb->cmd, "UPDATE File SET MD5='%s' WHERE FileId=%d", MD5, FileId);
+   Mmsg(&mdb->cmd, "UPDATE File SET MD5='%s' WHERE FileId=%u", MD5, FileId);
    stat = UPDATE_DB(mdb, mdb->cmd);
    db_unlock(mdb);
    return stat;
@@ -74,7 +74,7 @@ int db_mark_file_record(B_DB *mdb, FileId_t FileId, JobId_t JobId)
    int stat;
 
    db_lock(mdb);
-   Mmsg(&mdb->cmd, "UPDATE File SET MarkId=%d WHERE FileId=%d", JobId, FileId);
+   Mmsg(&mdb->cmd, "UPDATE File SET MarkId=%u WHERE FileId=%u", JobId, FileId);
    stat = UPDATE_DB(mdb, mdb->cmd);
    db_unlock(mdb);
    return stat;
@@ -103,7 +103,7 @@ db_update_job_start_record(B_DB *mdb, JOB_DBR *jr)
 
    db_lock(mdb);
    Mmsg(&mdb->cmd, "UPDATE Job SET Level='%c', StartTime='%s', \
-ClientId=%d, JobTDate=%s WHERE JobId=%d",
+ClientId=%u, JobTDate=%s WHERE JobId=%u",
       (char)(jr->Level), dt, jr->ClientId, edit_uint64(JobTDate, ed1), jr->JobId);
    stat = UPDATE_DB(mdb, mdb->cmd);
    db_unlock(mdb);
@@ -137,8 +137,8 @@ db_update_job_end_record(B_DB *mdb, JOB_DBR *jr)
    db_lock(mdb);
    Mmsg(&mdb->cmd,
       "UPDATE Job SET JobStatus='%c', EndTime='%s', \
-ClientId=%d, JobBytes=%s, JobFiles=%d, JobErrors=%d, VolSessionId=%d, \
-VolSessionTime=%d, PoolId=%d, FileSetId=%d, JobTDate=%s WHERE JobId=%d",
+ClientId=%u, JobBytes=%s, JobFiles=%u, JobErrors=%u, VolSessionId=%u, \
+VolSessionTime=%u, PoolId=%u, FileSetId=%u, JobTDate=%s WHERE JobId=%u",
       (char)(jr->JobStatus), dt, jr->ClientId, edit_uint64(jr->JobBytes, ed1), 
       jr->JobFiles, jr->JobErrors, jr->VolSessionId, jr->VolSessionTime, 
       jr->PoolId, jr->FileSetId, edit_uint64(JobTDate, ed2), jr->JobId);
@@ -157,7 +157,7 @@ db_update_pool_record(B_DB *mdb, POOL_DBR *pr)
    db_lock(mdb);
    Mmsg(&mdb->cmd,
 "UPDATE Pool SET NumVols=%d, MaxVols=%d, UseOnce=%d, UseCatalog=%d, \
-AcceptAnyVolume=%d, LabelFormat='%s' WHERE PoolId=%d",
+AcceptAnyVolume=%d, LabelFormat='%s' WHERE PoolId=%u",
       pr->NumVols, pr->MaxVols, pr->UseOnce, pr->UseCatalog,
       pr->AcceptAnyVolume, pr->LabelFormat, pr->PoolId);
 
@@ -195,9 +195,9 @@ db_update_media_record(B_DB *mdb, MEDIA_DBR *mr)
       Dmsg1(400, "Firstwritten stat=%d\n", stat);
    }
 
-   Mmsg(&mdb->cmd, "UPDATE Media SET VolJobs=%d,\
- VolFiles=%d, VolBlocks=%d, VolBytes=%s, VolMounts=%d, VolErrors=%d,\
- VolWrites=%d, VolMaxBytes=%s, LastWritten='%s', VolStatus='%s',\
+   Mmsg(&mdb->cmd, "UPDATE Media SET VolJobs=%u,\
+ VolFiles=%u, VolBlocks=%u, VolBytes=%s, VolMounts=%u, VolErrors=%u,\
+ VolWrites=%u, VolMaxBytes=%s, LastWritten='%s', VolStatus='%s',\
  Slot=%d WHERE VolumeName='%s'",
    mr->VolJobs, mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1),
    mr->VolMounts, mr->VolErrors, mr->VolWrites, 
index 4a94c93a465750e7270c0744022c66aa732d2b9d..5c1667cce6f616ea5457aa5e22b7ab4235bbde1b 100644 (file)
@@ -129,7 +129,7 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
       Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname);
       break;
    case FT_NOACCESS:
-      Jmsg(jcr, M_NOTSAVED, -1, _("     Could not access %s: ERR=%s"), ff_pkt->fname, 
+      Jmsg(jcr, M_NOTSAVED, -1, _("     Could not access %s: ERR=%s\n"), ff_pkt->fname, 
         strerror(ff_pkt->ff_errno));
       return 1;
    case FT_NOFOLLOW:
@@ -160,7 +160,7 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
         strerror(ff_pkt->ff_errno));
       return 1;
    default:
-      Jmsg(jcr, M_NOTSAVED, 0, _("Unknown file type %d; not saved: %s\n"), ff_pkt->type, ff_pkt->fname);
+      Jmsg(jcr, M_NOTSAVED, 0,  _("     Unknown file type %d; not saved: %s\n"), ff_pkt->type, ff_pkt->fname);
       return 1;
    }
 
@@ -168,7 +168,7 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
         ff_pkt->statp.st_size > 0) {
       if ((fid = open(ff_pkt->fname, O_RDONLY | O_BINARY)) < 0) {
         ff_pkt->ff_errno = errno;
-         Jmsg(jcr, M_NOTSAVED, -1, _("Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
+         Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
         return 1;
       }
    } else {
@@ -276,7 +276,7 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
            if (compress2((Bytef *)jcr->compress_buf, &compress_len, 
                  (const Bytef *)sd->msg, (uLong)sd->msglen,
                  ff_pkt->GZIP_level)  != Z_OK) {
-               Jmsg(jcr, M_ERROR, 0, _("Compression error\n"));
+               Jmsg(jcr, M_FATAL, 0, _("Compression error\n"));
               sd->msg = msgsave;
               sd->msglen = 0;
               close(fid);
@@ -312,8 +312,7 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
       } /* end while */
 
       if (sd->msglen < 0) {
-         Jmsg(jcr, M_ERROR, 0, _("Error during save reading ERR=%s\n"), ff_pkt->fname, 
-           strerror(ff_pkt->ff_errno));
+         Jmsg(jcr, M_ERROR, 0, _("Network error. ERR=%s\n"), bnet_strerror(sd));
       }
 
       /* Send data termination poll signal to Storage daemon.
@@ -331,7 +330,7 @@ static int save_file(FF_PKT *ff_pkt, void *ijcr)
         return 0;
       } else {
          if (strcmp(sd->msg, "3000 OK\n") != 0) {
-           Jmsg1(jcr, M_ERROR, 0, _("Job aborted by Storage daemon: %s\n"), sd->msg);
+           Jmsg1(jcr, M_FATAL, 0, _("Job aborted by Storage daemon: %s\n"), sd->msg);
           close(fid);
           return 0;
         }
index c675a4776ce03e401ea76154d0688988b72a9ecd..3835553c441bee0fe37219973bdaf8e3fc02edc7 100644 (file)
@@ -128,7 +128,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt)
       Jmsg(jcr, M_NOTSAVED, -1, _("     Could not open directory %s: ERR=%s\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
       return 1;
    default:
-      Jmsg(jcr, M_NOTSAVED, 0, _("Unknown file type %d: %s\n"), ff_pkt->type, ff_pkt->fname);
+      Jmsg(jcr, M_NOTSAVED, 0, _("     Unknown file type %d: %s\n"), ff_pkt->type, ff_pkt->fname);
       return 1;
    }
 
@@ -137,7 +137,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt)
         ff_pkt->statp.st_size > 0) {
       if ((fid = open(ff_pkt->fname, O_RDONLY | O_BINARY)) < 0) {
         ff_pkt->ff_errno = errno;
-         Jmsg(jcr, M_NOTSAVED, -1, _("Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
+         Jmsg(jcr, M_NOTSAVED, -1, _("     Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno));
         return 1;
       }
    } else {
@@ -171,7 +171,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt)
     */
    /* Send file attributes to Director (note different format than for Storage) */
    Dmsg2(400, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, ff_pkt->fname);
-   if (ff_pkt->type == FT_LNK || ff_pkt->tye == FT_LNKSAVED) {
+   if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
       stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
                    STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname, 
                    0, attribs, 0, ff_pkt->link, 0);
index 09d58ec275ef405595f1dcfb01c4ab67d3b452b7..911a7a2e472859dac363554f9d62819cb27c5058 100755 (executable)
@@ -498,7 +498,7 @@ void close_msg(void *vjcr)
             * make sure we are not closing the daemon messages, otherwise
             * kaboom.
             */
-           if (stat < 0 && msgs != daemon_msgs) {
+           if (stat < 0 && msgs != daemon_msgs && errno != ECHILD) {
                Emsg1(M_ERROR, 0, _("Mail program terminated in error.\nCMD=%s\n"),
                  cmd);
            }
@@ -644,7 +644,7 @@ void dispatch_message(void *vjcr, int type, int level, char *msg)
                   /* Messages to the operator go one at a time */
                   stat = pclose(d->fd);
                   d->fd = NULL;
-                  if (stat < 0) {
+                  if (stat < 0 && errno != ECHILD) {
                       Emsg1(M_ERROR, 0, _("Operator mail program terminated in error.\nCMD=%s\n"),
                         mcmd);
                   }