]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/newvol.c
This commit was manufactured by cvs2svn to create tag
[bacula/bacula] / bacula / src / dird / newvol.c
1 /*
2  *
3  *   Bacula Director -- newvol.c -- creates new Volumes in
4  *    catalog Media table from the LabelFormat specification.
5  *
6  *     Kern Sibbald, May MMI
7  *
8  *    This routine runs as a thread and must be thread reentrant.
9  *
10  *  Basic tasks done here:
11  *      If possible create a new Media entry
12  *
13  *   Version $Id$
14  */
15 /*
16    Copyright (C) 2000-2005 Kern Sibbald
17
18    This program is free software; you can redistribute it and/or
19    modify it under the terms of the GNU General Public License
20    version 2 as amended with additional clauses defined in the
21    file LICENSE in the main source directory.
22
23    This program is distributed in the hope that it will be useful,
24    but WITHOUT ANY WARRANTY; without even the implied warranty of
25    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
26    the file LICENSE for additional details.
27
28  */
29
30 #include "bacula.h"
31 #include "dird.h"
32
33 /* Forward referenced functions */
34 static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr);
35 static bool perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr);
36
37
38 /*
39  * Automatic Volume name creation using the LabelFormat
40  *
41  *  The media record must have the PoolId filled in when
42  *   calling this routine.
43  */
44 bool newVolume(JCR *jcr, MEDIA_DBR *mr)
45 {
46    POOL_DBR pr;
47
48    memset(&pr, 0, sizeof(pr));
49
50    /* See if we can create a new Volume */
51    db_lock(jcr->db);
52    pr.PoolId = mr->PoolId;
53    if (!db_get_pool_record(jcr, jcr->db, &pr)) {
54       goto bail_out;
55    }
56    if (pr.MaxVols == 0 || pr.NumVols < pr.MaxVols) {
57       memset(mr, 0, sizeof(MEDIA_DBR));
58       set_pool_dbr_defaults_in_media_dbr(mr, &pr);
59       jcr->VolumeName[0] = 0;
60       bstrncpy(mr->MediaType, jcr->store->media_type, sizeof(mr->MediaType));
61       if (generate_job_event(jcr, "NewVolume") == 1 && jcr->VolumeName[0] &&
62           is_volume_name_legal(NULL, jcr->VolumeName)) {
63          bstrncpy(mr->VolumeName, jcr->VolumeName, sizeof(mr->VolumeName));
64       /* Check for special characters */
65       } else if (pr.LabelFormat[0] && pr.LabelFormat[0] != '*') {
66          if (is_volume_name_legal(NULL, pr.LabelFormat)) {
67             /* No special characters, so apply simple algorithm */
68             if (!create_simple_name(jcr, mr, &pr)) {
69                goto bail_out;
70             }
71          } else {  /* try full substitution */
72             /* Found special characters, so try substitution */
73             if (!perform_full_name_substitution(jcr, mr, &pr)) {
74                goto bail_out;
75             }
76             if (!is_volume_name_legal(NULL, mr->VolumeName)) {
77                Jmsg(jcr, M_ERROR, 0, _("Illegal character in Volume name \"%s\"\n"),
78                   mr->VolumeName);
79                goto bail_out;
80             }
81          }
82       } else {                                       
83          goto bail_out;
84       }
85       pr.NumVols++;
86       if (db_create_media_record(jcr, jcr->db, mr) &&
87          db_update_pool_record(jcr, jcr->db, &pr)) {
88          db_unlock(jcr->db);
89          Jmsg(jcr, M_INFO, 0, _("Created new Volume \"%s\" in catalog.\n"), mr->VolumeName);
90          Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName);
91          return true;
92       } else {
93          Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
94       }
95    }
96 bail_out:
97    db_unlock(jcr->db);
98    return false;
99 }
100
101 static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr)
102 {
103    char name[MAXSTRING];
104    char num[20];
105
106    /* See if volume already exists */
107    mr->VolumeName[0] = 0;
108    bstrncpy(name, pr->LabelFormat, sizeof(name));
109    for (int i=pr->NumVols+1; i<(int)pr->NumVols+11; i++) {
110       MEDIA_DBR tmr;
111       memset(&tmr, 0, sizeof(tmr));
112       sprintf(num, "%04d", i);
113       bstrncpy(tmr.VolumeName, name, sizeof(tmr.VolumeName));
114       bstrncat(tmr.VolumeName, num, sizeof(tmr.VolumeName));
115       if (db_get_media_record(jcr, jcr->db, &tmr)) {
116          Jmsg(jcr, M_WARNING, 0,
117              _("Wanted to create Volume \"%s\", but it already exists. Trying again.\n"),
118              tmr.VolumeName);
119          continue;
120       }
121       bstrncpy(mr->VolumeName, name, sizeof(mr->VolumeName));
122       bstrncat(mr->VolumeName, num, sizeof(mr->VolumeName));
123       break;                    /* Got good name */
124    }
125    if (mr->VolumeName[0] == 0) {
126       Jmsg(jcr, M_ERROR, 0, _("Too many failures. Giving up creating Volume name.\n"));
127       return false;
128    }
129    return true;
130 }
131
132 /*
133  * Perform full substitution on Label
134  */
135 static bool perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr)
136 {
137    bool ok = false;
138    POOLMEM *label = get_pool_memory(PM_FNAME);
139    jcr->NumVols = pr->NumVols;
140    if (variable_expansion(jcr, pr->LabelFormat, &label)) {
141       bstrncpy(mr->VolumeName, label, sizeof(mr->VolumeName));
142       ok = true;
143    }
144    free_pool_memory(label);
145    return ok;
146 }