2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
5 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
7 The original author of Bacula is Kern Sibbald, with contributions
8 from many others, a complete list can be found in the file AUTHORS.
10 You may use this file and others of this release according to the
11 license defined in the LICENSE file, which includes the Affero General
12 Public License, v3.0 ("AGPLv3") and some additional permissions and
13 terms pursuant to its AGPLv3 Section 7.
15 This notice must be preserved when any source code is
16 conveyed and/or propagated.
18 Bacula(R) is a registered trademark of Kern Sibbald.
22 * Bacula Director -- newvol.c -- creates new Volumes in
23 * catalog Media table from the LabelFormat specification.
25 * Kern Sibbald, May MMI
27 * This routine runs as a thread and must be thread reentrant.
29 * Basic tasks done here:
30 * If possible create a new Media entry
37 /* Forward referenced functions */
38 static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr);
39 static bool perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr);
43 * Automatic Volume name creation using the LabelFormat
45 * The media record must have the PoolId filled in when
46 * calling this routine.
48 bool newVolume(JCR *jcr, MEDIA_DBR *mr, STORE *store)
52 memset(&pr, 0, sizeof(pr));
54 /* See if we can create a new Volume */
56 pr.PoolId = mr->PoolId;
57 if (!db_get_pool_numvols(jcr, jcr->db, &pr)) {
60 if (pr.MaxVols == 0 || pr.NumVols < pr.MaxVols) {
62 set_pool_dbr_defaults_in_media_dbr(mr, &pr);
63 jcr->VolumeName[0] = 0;
64 bstrncpy(mr->MediaType, jcr->wstore->media_type, sizeof(mr->MediaType));
65 generate_plugin_event(jcr, bDirEventNewVolume); /* return void... */
66 if (jcr->VolumeName[0] && is_volume_name_legal(NULL, jcr->VolumeName)) {
67 bstrncpy(mr->VolumeName, jcr->VolumeName, sizeof(mr->VolumeName));
68 /* Check for special characters */
69 } else if (pr.LabelFormat[0] && pr.LabelFormat[0] != '*') {
70 if (is_volume_name_legal(NULL, pr.LabelFormat)) {
71 /* No special characters, so apply simple algorithm */
72 if (!create_simple_name(jcr, mr, &pr)) {
75 } else { /* try full substitution */
76 /* Found special characters, so try substitution */
77 if (!perform_full_name_substitution(jcr, mr, &pr)) {
80 if (!is_volume_name_legal(NULL, mr->VolumeName)) {
81 Jmsg(jcr, M_ERROR, 0, _("Illegal character in Volume name \"%s\"\n"),
91 set_storageid_in_mr(store, mr);
92 if (db_create_media_record(jcr, jcr->db, mr) &&
93 db_update_pool_record(jcr, jcr->db, &pr)) {
94 Jmsg(jcr, M_INFO, 0, _("Created new Volume=\"%s\", Pool=\"%s\", MediaType=\"%s\" in catalog.\n"),
95 mr->VolumeName, pr.Name, mr->MediaType);
96 Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName);
100 Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
108 static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr)
110 char name[MAXSTRING];
113 POOL_MEM query(PM_MESSAGE);
116 /* See if volume already exists */
117 mr->VolumeName[0] = 0;
118 bstrncpy(name, pr->LabelFormat, sizeof(name));
120 /* TODO: Remove Pool as it is not used in the query */
121 Mmsg(query, "SELECT MAX(MediaId) FROM Media,Pool WHERE Pool.PoolId=%s",
122 edit_int64(pr->PoolId, ed1));
123 if (!db_sql_query(jcr->db, query.c_str(), db_int64_handler, (void *)&ctx)) {
124 Jmsg(jcr, M_WARNING, 0, _("SQL failed, but ignored. ERR=%s\n"), db_strerror(jcr->db));
125 ctx.value = pr->NumVols+1;
127 for (int i=(int)ctx.value+1; i<(int)ctx.value+100; i++) {
129 sprintf(num, "%04d", i);
130 bstrncpy(tmr.VolumeName, name, sizeof(tmr.VolumeName));
131 bstrncat(tmr.VolumeName, num, sizeof(tmr.VolumeName));
132 if (db_get_media_record(jcr, jcr->db, &tmr)) {
133 Jmsg(jcr, M_WARNING, 0,
134 _("Wanted to create Volume \"%s\", but it already exists. Trying again.\n"),
138 bstrncpy(mr->VolumeName, name, sizeof(mr->VolumeName));
139 bstrncat(mr->VolumeName, num, sizeof(mr->VolumeName));
140 break; /* Got good name */
142 if (mr->VolumeName[0] == 0) {
143 Jmsg(jcr, M_ERROR, 0, _("Too many failures. Giving up creating Volume name.\n"));
150 * Perform full substitution on Label
152 static bool perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr)
155 POOLMEM *label = get_pool_memory(PM_FNAME);
156 jcr->NumVols = pr->NumVols;
157 if (variable_expansion(jcr, pr->LabelFormat, &label)) {
158 bstrncpy(mr->VolumeName, label, sizeof(mr->VolumeName));
161 free_pool_memory(label);