}
Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"),
rctx.stream);
- Dmsg2(0, "None of above!!! stream=%d data=%s\n", rctx.stream,sd->msg);
+ Dmsg2(0, "Unknown stream=%d data=%s\n", rctx.stream, sd->msg);
break;
} /* end switch(stream) */
--- /dev/null
+/*
+ Bacula® - The Network Backup Solution
+
+ Copyright (C) 2007 Kern Sibbald
+
+ The main author of Bacula is Kern Sibbald, with contributions from
+ many others, a complete list can be found in the file AUTHORS.
+ This program is Free Software; you can redistribute it and/or
+ modify it under the terms of version two of the GNU General Public
+ License as published by the Free Software Foundation, which is
+ listed in the file LICENSE.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Bacula® is a registered trademark of John Walker.
+ The licensor of Bacula is the Free Software Foundation Europe
+ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+ Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ * Written by Kern Sibbald, July 2005 to replace idcache.c
+ *
+ * Program to convert uid and gid into names, and cache the results
+ * for preformance reasons.
+ */
+
+#include "bacula.h"
+
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+struct guitem {
+ dlink link;
+ char *name;
+ union {
+ uid_t uid;
+ gid_t gid;
+ };
+};
+
+class guid_list {
+public:
+ dlist *uid_list;
+ dlist *gid_list;
+
+ char *uid_to_name(uid_t uid, char *name, int maxlen);
+ char *gid_to_name(gid_t gid, char *name, int maxlen);
+};
+
+guid_list *new_guid_list()
+{
+ guid_list *list;
+ guitem *item = NULL;
+ list = (guid_list *)malloc(sizeof(guid_list));
+ list->uid_list = New(dlist(item, &item->link));
+ list->gid_list = New(dlist(item, &item->link));
+ return list;
+}
+
+void free_guid_list(guid_list *list)
+{
+ guitem *item;
+ foreach_dlist(item, list->uid_list) {
+ free(item->name);
+ }
+ foreach_dlist(item, list->gid_list) {
+ free(item->name);
+ }
+ delete list->uid_list;
+ delete list->gid_list;
+ free(list);
+}
+
+static int uid_compare(void *item1, void *item2)
+{
+ guitem *i1 = (guitem *)item1;
+ guitem *i2 = (guitem *)item2;
+ if (i1->uid < i2->uid) {
+ return -1;
+ } else if (i1->uid > i2->uid) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int gid_compare(void *item1, void *item2)
+{
+ guitem *i1 = (guitem *)item1;
+ guitem *i2 = (guitem *)item2;
+ if (i1->gid < i2->gid) {
+ return -1;
+ } else if (i1->gid > i2->gid) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+static void get_uidname(uid_t uid, guitem *item)
+{
+#ifndef HAVE_WIN32
+ struct passwd *pwbuf;
+ P(mutex);
+ pwbuf = getpwuid(uid);
+ if (pwbuf != NULL && strcmp(pwbuf->pw_name, "????????") != 0) {
+ item->name = bstrdup(pwbuf->pw_name);
+ }
+ V(mutex);
+#endif
+}
+
+static void get_gidname(gid_t gid, guitem *item)
+{
+#ifndef HAVE_WIN32
+ struct group *grbuf;
+ P(mutex);
+ grbuf = getgrgid(gid);
+ if (grbuf != NULL && strcmp(grbuf->gr_name, "????????") != 0) {
+ item->name = bstrdup(grbuf->gr_name);
+ }
+ V(mutex);
+#endif
+}
+
+
+char *guid_list::uid_to_name(uid_t uid, char *name, int maxlen)
+{
+ guitem sitem, *item, *fitem;
+ sitem.uid = uid;
+ char buf[50];
+
+ item = (guitem *)uid_list->binary_search(&sitem, uid_compare);
+ Dmsg2(900, "uid=%d item=%p\n", uid, item);
+ if (!item) {
+ item = (guitem *)malloc(sizeof(guitem));
+ item->uid = uid;
+ item->name = NULL;
+ get_uidname(uid, item);
+ if (!item->name) {
+ item->name = bstrdup(edit_int64(uid, buf));
+ Dmsg2(900, "set uid=%d name=%s\n", uid, item->name);
+ }
+ fitem = (guitem *)uid_list->binary_insert(item, uid_compare);
+ if (fitem != item) { /* item already there this shouldn't happen */
+ free(item);
+ item = fitem;
+ }
+ }
+ bstrncpy(name, item->name, maxlen);
+ return name;
+}
+
+char *guid_list::gid_to_name(gid_t gid, char *name, int maxlen)
+{
+ guitem sitem, *item, *fitem;
+ sitem.gid = gid;
+ char buf[50];
+
+ item = (guitem *)uid_list->binary_search(&sitem, gid_compare);
+ if (!item) {
+ item = (guitem *)malloc(sizeof(guitem));
+ item->gid = gid;
+ item->name = NULL;
+ get_gidname(gid, item);
+ if (!item->name) {
+ item->name = bstrdup(edit_int64(gid, buf));
+ }
+ fitem = (guitem *)gid_list->binary_insert(item, gid_compare);
+ if (fitem != item) { /* item already there this shouldn't happen */
+ free(item);
+ item = fitem;
+ }
+ }
+
+ bstrncpy(name, item->name, maxlen);
+ return name;
+}
+
+#ifdef TEST_PROGRAM
+
+int main()
+{
+ int i;
+ guid_list *list;
+ char ed1[50], ed2[50];
+ list = new_guid_list();
+ for (i=0; i<1001; i++) {
+ printf("uid=%d name=%s gid=%d name=%s\n", i, list->uid_to_name(i, ed1, sizeof(ed1)),
+ i, list->gid_to_name(i, ed2, sizeof(ed2)));
+ printf("uid=%d name=%s gid=%d name=%s\n", i, list->uid_to_name(i, ed1, sizeof(ed1)),
+ i, list->gid_to_name(i, ed2, sizeof(ed2)));
+ }
+
+ free_guid_list(list);
+ sm_dump(false);
+
+ return 0;
+}
+
+#endif
int vol_label_status;
int retry = 0;
- Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
+ Dmsg1(950, "jcr->dcr=%p\n", jcr->dcr);
dev->dblock(BST_DOING_ACQUIRE);
if (dev->num_writers > 0) {
* same as the current drive, we attempt to find the same
* device that was used to write the orginal volume. If
* found, we switch to using that device.
+ *
+ * N.B. A lot of routines rely on the dcr pointer not changing
+ * read_records.c even has multiple dcrs cached, so we take care
+ * here to release all important parts of the dcr and re-acquire
+ * them such as the block pointer (size may change), but we do
+ * not release the dcr.
*/
Dmsg2(50, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
if (dcr->media_type[0] && strcmp(dcr->media_type, dev->device->media_type) != 0) {
Jmsg3(jcr, M_INFO, 0, _("Changing device. Want Media Type=\"%s\" have=\"%s\"\n"
" device=%s\n"),
dcr->media_type, dev->device->media_type, dev->print_name());
+ Dmsg3(50, "Changing device. Want Media Type=\"%s\" have=\"%s\"\n"
+ " device=%s\n",
+ dcr->media_type, dev->device->media_type, dev->print_name());
dev->dunblock(DEV_UNLOCKED);
- detach_dcr_from_dev(dcr); /* release old device */
lock_reservations();
memset(&rctx, 0, sizeof(RCTX));
bstrncpy(store->pool_type, dcr->pool_type, sizeof(store->pool_type));
store->append = false;
rctx.store = store;
+ dcr->keep_dcr = true; /* do not free the dcr */
+ release_device(dcr);
+ dcr->keep_dcr = false;
/*
- * Note, if search_for_device() succeeds, we get a new dcr,
- * which we do not use except for the dev info.
+ * Search for a new device
*/
stat = search_res_for_device(rctx);
release_reserve_messages(jcr); /* release queued messages */
unlock_reservations();
- dev->dblock(BST_DOING_ACQUIRE);
+
if (stat == 1) {
+ dev = dcr->dev; /* get new device pointer */
+ dev->dblock(BST_DOING_ACQUIRE);
dcr->VolumeName[0] = 0;
Jmsg(jcr, M_INFO, 0, _("Media Type change. New device %s chosen.\n"),
dev->print_name());
+ Dmsg1(50, "Media Type change. New device %s chosen.\n", dev->print_name());
+
bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
dcr->VolCatInfo.Slot = vol->Slot;
bstrncpy(dcr->pool_name, store->pool_name, sizeof(dcr->pool_name));
bstrncpy(dcr->pool_type, store->pool_type, sizeof(dcr->pool_type));
- } else if (stat == 0) { /* device busy */
- Pmsg1(000, "Device %s is busy.\n", vol->device);
} else {
/* error */
Jmsg1(jcr, M_FATAL, 0, _("No suitable device found to read Volume \"%s\"\n"),
vol->VolumeName);
+ Dmsg1(50, "No suitable device found to read Volume \"%s\"\n", vol->VolumeName);
goto get_out;
}
}
dev->print_name(), dcr->VolumeName, dev->bstrerror());
goto default_path;
}
- Dmsg1(100, "opened dev %s OK\n", dev->print_name());
+ Dmsg1(50, "opened dev %s OK\n", dev->print_name());
/* Read Volume Label */
-
- Dmsg0(200, "calling read-vol-label\n");
+ Dmsg0(50, "calling read-vol-label\n");
vol_label_status = read_dev_volume_label(dcr);
switch (vol_label_status) {
case VOL_OK:
get_out:
dev->dlock();
- if (dcr->reserved_device) {
+ if (dcr && dcr->reserved_device) {
dev->reserved_device--;
- Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
+ Dmsg2(50, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
dcr->reserved_device = false;
}
dev->dunblock(DEV_LOCKED);
- Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
+ Dmsg1(950, "jcr->dcr=%p\n", jcr->dcr);
return ok;
}
Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
pthread_cond_broadcast(&wait_device_release);
dev->dunlock();
- if (jcr->read_dcr == dcr) {
- jcr->read_dcr = NULL;
- }
- if (jcr->dcr == dcr) {
- jcr->dcr = NULL;
+ if (dcr->keep_dcr) {
+ detach_dcr_from_dev(dcr);
+ } else {
+ if (jcr->read_dcr == dcr) {
+ jcr->read_dcr = NULL;
+ }
+ if (jcr->dcr == dcr) {
+ jcr->dcr = NULL;
+ }
+ free_dcr(dcr);
}
- free_dcr(dcr);
Dmsg2(100, "===== Device %s released by JobId=%u\n", dev->print_name(),
(uint32_t)jcr->JobId);
return ok;
bool any_volume; /* Any OK for dir_find_next... */
bool attached_to_dev; /* set when attached to dev */
bool volume_in_use; /* set in dir_find_next_appendable_volume() */
+ bool keep_dcr; /* do not free dcr in release_dcr */
uint32_t VolFirstIndex; /* First file index this Volume */
uint32_t VolLastIndex; /* Last file index this Volume */
uint32_t FileIndex; /* Current File Index */
-/*
- * Read code for Storage daemon
- *
- * Kern Sibbald, November MM
- *
- * Version $Id$
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * Read code for Storage daemon
+ *
+ * Kern Sibbald, November MM
+ *
+ * Version $Id$
+ */
#include "bacula.h"
#include "stored.h"
if (jcr->NumReadVolumes == 0) {
Jmsg(jcr, M_FATAL, 0, _("No Volume names found for restore.\n"));
free_restore_volume_list(jcr);
- bnet_fsend(fd, FD_error);
+ fd->fsend(FD_error);
return false;
}
/* Ready device for reading */
if (!acquire_device_for_read(dcr)) {
free_restore_volume_list(jcr);
- bnet_fsend(fd, FD_error);
+ fd->fsend(FD_error);
return false;
}
/* Tell File daemon we will send data */
- bnet_fsend(fd, OK_data);
+ fd->fsend(OK_data);
ok = read_records(dcr, record_cb, mount_next_read_volume);
/* Send end of data to FD */
- bnet_sig(fd, BNET_EOD);
+ fd->signal(BNET_EOD);
if (!release_device(jcr->read_dcr)) {
ok = false;
rec->data_len);
/* Send record header to File daemon */
- if (!bnet_fsend(fd, rec_header, rec->VolSessionId, rec->VolSessionTime,
+ if (!fd->fsend(rec_header, rec->VolSessionId, rec->VolSessionTime,
rec->FileIndex, rec->Stream, rec->data_len)) {
Pmsg1(000, _(">filed: Error Hdr=%s\n"), fd->msg);
Jmsg1(jcr, M_FATAL, 0, _("Error sending to File daemon. ERR=%s\n"),
- bnet_strerror(fd));
+ fd->bstrerror());
return false;
} else {
Dmsg1(400, ">filed: Hdr=%s\n", fd->msg);
/* Send data record to File daemon */
save_msg = fd->msg; /* save fd message pointer */
- fd->msg = rec->data; /* pass data directly to bnet_send */
+ fd->msg = rec->data; /* pass data directly to the FD */
fd->msglen = rec->data_len;
Dmsg1(400, ">filed: send %d bytes data.\n", fd->msglen);
- if (!bnet_send(fd)) {
- Pmsg1(000, _("Error sending to FD. ERR=%s\n"), bnet_strerror(fd));
+ if (!fd->send()) {
+ Pmsg1(000, _("Error sending to FD. ERR=%s\n"), fd->bstrerror());
Jmsg1(jcr, M_FATAL, 0, _("Error sending to File daemon. ERR=%s\n"),
- bnet_strerror(fd));
+ fd->bstrerror());
ok = false;
}
-/*
- *
- * This routine provides a routine that will handle all
- * the gory little details of reading a record from a Bacula
- * archive. It uses a callback to pass you each record in turn,
- * as well as a callback for mounting the next tape. It takes
- * care of reading blocks, applying the bsr, ...
- * Note, this routine is really the heart of the restore routines,
- * and we are *really* bit pushing here so be careful about making
- * any modifications.
- *
- * Kern E. Sibbald, August MMII
- *
- * Version $Id$
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2002-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2002-2007 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ *
+ * This routine provides a routine that will handle all
+ * the gory little details of reading a record from a Bacula
+ * archive. It uses a callback to pass you each record in turn,
+ * as well as a callback for mounting the next tape. It takes
+ * care of reading blocks, applying the bsr, ...
+ * Note, this routine is really the heart of the restore routines,
+ * and we are *really* bit pushing here so be careful about making
+ * any modifications.
+ *
+ * Kern E. Sibbald, August MMII
+ *
+ * Version $Id$
+ */
#include "bacula.h"
#include "stored.h"
jcr->mount_next_volume = false;
/*
* The Device can change at the end of a tape, so refresh it
- * from the dcr.
+ * and the block from the dcr.
*/
dev = dcr->dev;
+ block = dcr->block;
/*
* We just have a new tape up, now read the label (first record)
* and pass it off to the callback routine, then continue
#undef VERSION
#define VERSION "2.1.29"
-#define BDATE "04 August 2007"
-#define LSMDATE "04Aug07"
+#define BDATE "06 August 2007"
+#define LSMDATE "06Aug07"
#define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n"
#define BYEAR "2007" /* year for copyright messages in progs */
Technical notes on version 2.1
General:
+06Aug07
+kes Correct seg fault when switching tape drives during restore.
+kes Commit uid_gid_name.c (replacement for idcache.c), but will not
+ be used until after 2.2.0 release.
04Aug07
kes Remove fnmatch() in SD that permitted wild card specifications.
This fixes bug #914.