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 Mmsg(query, "SELECT MAX(MediaId) FROM Media,Pool WHERE Pool.PoolId=%s",
121 edit_int64(pr->PoolId, ed1));
122 if (!db_sql_query(jcr->db, query.c_str(), db_int64_handler, (void *)&ctx)) {
123 Jmsg(jcr, M_WARNING, 0, _("SQL failed, but ignored. ERR=%s\n"), db_strerror(jcr->db));
124 ctx.value = pr->NumVols+1;
126 for (int i=(int)ctx.value+1; i<(int)ctx.value+100; i++) {
128 sprintf(num, "%04d", i);
129 bstrncpy(tmr.VolumeName, name, sizeof(tmr.VolumeName));
130 bstrncat(tmr.VolumeName, num, sizeof(tmr.VolumeName));
131 if (db_get_media_record(jcr, jcr->db, &tmr)) {
132 Jmsg(jcr, M_WARNING, 0,
133 _("Wanted to create Volume \"%s\", but it already exists. Trying again.\n"),
137 bstrncpy(mr->VolumeName, name, sizeof(mr->VolumeName));
138 bstrncat(mr->VolumeName, num, sizeof(mr->VolumeName));
139 break; /* Got good name */
141 if (mr->VolumeName[0] == 0) {
142 Jmsg(jcr, M_ERROR, 0, _("Too many failures. Giving up creating Volume name.\n"));
149 * Perform full substitution on Label
151 static bool perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr)
154 POOLMEM *label = get_pool_memory(PM_FNAME);
155 jcr->NumVols = pr->NumVols;
156 if (variable_expansion(jcr, pr->LabelFormat, &label)) {
157 bstrncpy(mr->VolumeName, label, sizeof(mr->VolumeName));
160 free_pool_memory(label);