2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Bacula Director -- newvol.c -- creates new Volumes in
22 * catalog Media table from the LabelFormat specification.
24 * Kern Sibbald, May MMI
26 * This routine runs as a thread and must be thread reentrant.
28 * Basic tasks done here:
29 * If possible create a new Media entry
36 /* Forward referenced functions */
37 static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr);
38 static bool perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr);
42 * Automatic Volume name creation using the LabelFormat
44 * The media record must have the PoolId filled in when
45 * calling this routine.
47 bool newVolume(JCR *jcr, MEDIA_DBR *mr, STORE *store)
51 memset(&pr, 0, sizeof(pr));
53 /* See if we can create a new Volume */
55 pr.PoolId = mr->PoolId;
56 if (!db_get_pool_numvols(jcr, jcr->db, &pr)) {
59 if (pr.MaxVols == 0 || pr.NumVols < pr.MaxVols) {
61 set_pool_dbr_defaults_in_media_dbr(mr, &pr);
62 jcr->VolumeName[0] = 0;
63 bstrncpy(mr->MediaType, jcr->wstore->media_type, sizeof(mr->MediaType));
64 generate_plugin_event(jcr, bDirEventNewVolume); /* return void... */
65 if (jcr->VolumeName[0] && is_volume_name_legal(NULL, jcr->VolumeName)) {
66 bstrncpy(mr->VolumeName, jcr->VolumeName, sizeof(mr->VolumeName));
67 /* Check for special characters */
68 } else if (pr.LabelFormat[0] && pr.LabelFormat[0] != '*') {
69 if (is_volume_name_legal(NULL, pr.LabelFormat)) {
70 /* No special characters, so apply simple algorithm */
71 if (!create_simple_name(jcr, mr, &pr)) {
74 } else { /* try full substitution */
75 /* Found special characters, so try substitution */
76 if (!perform_full_name_substitution(jcr, mr, &pr)) {
79 if (!is_volume_name_legal(NULL, mr->VolumeName)) {
80 Jmsg(jcr, M_ERROR, 0, _("Illegal character in Volume name \"%s\"\n"),
90 set_storageid_in_mr(store, mr);
91 if (db_create_media_record(jcr, jcr->db, mr) &&
92 db_update_pool_record(jcr, jcr->db, &pr)) {
93 Jmsg(jcr, M_INFO, 0, _("Created new Volume=\"%s\", Pool=\"%s\", MediaType=\"%s\" in catalog.\n"),
94 mr->VolumeName, pr.Name, mr->MediaType);
95 Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName);
99 Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
107 static bool create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr)
109 char name[MAXSTRING];
112 POOL_MEM query(PM_MESSAGE);
115 /* See if volume already exists */
116 mr->VolumeName[0] = 0;
117 bstrncpy(name, pr->LabelFormat, sizeof(name));
119 /* TODO: Remove Pool as it is not used in the query */
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);