int object_store_device::d_close(int fd) { if (m_vfd) { dpl_status_t status; status = dpl_close(m_vfd); switch (status) { case DPL_SUCCESS: m_vfd = NULL; return 0; default: m_vfd = NULL; return droplet_errno_to_system_errno(status); } } else { errno = EBADF; return -1; } }
dpl_status_t dpltest_upload_file(dpl_ctx_t *ctx, char *path, char *blob_buf, int blob_size, int buffered, int block_size) { dpl_status_t ret, ret2; dpl_canned_acl_t canned_acl = DPL_CANNED_ACL_PRIVATE; dpl_dict_t *metadata = NULL; dpl_vfile_t *vfile = NULL; int retries = 0; dpl_vfile_flag_t flags = 0u; dpl_sysmd_t sysmd; int remain, buf_size, off; memset(&sysmd, 0, sizeof (sysmd)); sysmd.mask = DPL_SYSMD_MASK_CANNED_ACL; sysmd.canned_acl = canned_acl; flags = DPL_VFILE_FLAG_CREAT; //flags |= DPL_VFILE_FLAG_POST; if (!buffered) { flags |= DPL_VFILE_FLAG_ONESHOT; block_size = blob_size; } retry: if (retries >= 3) { fprintf(stderr, "too many retries: %s (%d)\n", dpl_status_str(ret), ret); ret = DPL_FAILURE; goto end; } retries++; ret2 = dpl_openwrite(ctx, path, DPL_FTYPE_REG, flags, NULL, metadata, &sysmd, blob_size, NULL, &vfile); if (DPL_SUCCESS != ret2) { if (DPL_ENOENT == ret2) { ret = DPL_ENOENT; } goto retry; } remain = blob_size; off = 0; while (remain > 0) { buf_size = MIN(remain, block_size); ret = dpl_write(vfile, blob_buf + off, buf_size); if (DPL_SUCCESS != ret) { fprintf(stderr, "write failed\n"); goto retry; } off += buf_size; remain -= buf_size; } ret = dpl_close(vfile); if (DPL_SUCCESS != ret) { fprintf(stderr, "close failed %s (%d)\n", dpl_status_str(ret), ret); goto retry; } vfile = NULL; ret = DPL_SUCCESS; end: if (NULL != metadata) dpl_dict_free(metadata); if (NULL != vfile) dpl_close(vfile); return ret; }
bool object_store_device::d_truncate(DCR *dcr) { /* * libdroplet doesn't have a truncate function so unlink the volume and create a new empty one. */ if (m_vfd) { dpl_status_t status; dpl_vfile_flag_t dpl_flags; dpl_option_t dpl_options; status = dpl_close(m_vfd); switch (status) { case DPL_SUCCESS: m_vfd = NULL; break; default: Mmsg2(errmsg, _("Failed to close %s using dpl_close(): ERR=%s.\n"), getVolCatName(), dpl_status_str(status)); return false; } status = dpl_unlink(m_ctx, getVolCatName()); switch (status) { case DPL_SUCCESS: break; default: Mmsg2(errmsg, _("Failed to unlink %s using dpl_unlink(): ERR=%s.\n"), getVolCatName(), dpl_status_str(status)); return false; } /* * Create some options for libdroplet. * * DPL_OPTION_NOALLOC - we provide the buffer to copy the data into * no need to let the library allocate memory we * need to free after copying the data. */ memset(&dpl_options, 0, sizeof(dpl_options)); dpl_options.mask |= DPL_OPTION_NOALLOC; dpl_flags = DPL_VFILE_FLAG_CREAT | DPL_VFILE_FLAG_RDWR; status = dpl_open(m_ctx, /* context */ getVolCatName(), /* locator */ dpl_flags, /* flags */ &dpl_options, /* options */ NULL, /* condition */ NULL, /* metadata */ NULL, /* sysmd */ NULL, /* query_params */ NULL, /* stream_status */ &m_vfd); switch (status) { case DPL_SUCCESS: break; default: Mmsg2(errmsg, _("Failed to open %s using dpl_open(): ERR=%s.\n"), getVolCatName(), dpl_status_str(status)); return false; } } return true; }
/* * Open a volume using libdroplet. */ int object_store_device::d_open(const char *pathname, int flags, int mode) { dpl_status_t status; dpl_vfile_flag_t dpl_flags; dpl_option_t dpl_options; #if 1 Mmsg1(errmsg, _("Object Storage devices are not yet supported, please disable %s\n"), dev_name); return -1; #endif /* * Initialize the droplet library when its not done previously. */ P(mutex); if (droplet_reference_count == 0) { status = dpl_init(); if (status != DPL_SUCCESS) { V(mutex); return -1; } dpl_set_log_func(object_store_logfunc); droplet_reference_count++; } V(mutex); if (!m_object_configstring) { int len; char *bp, *next_option; bool done; if (!dev_options) { Mmsg0(errmsg, _("No device options configured\n")); Emsg0(M_FATAL, 0, errmsg); return -1; } m_object_configstring = bstrdup(dev_options); bp = m_object_configstring; while (bp) { next_option = strchr(bp, ','); if (next_option) { *next_option++ = '\0'; } done = false; for (int i = 0; !done && device_options[i].name; i++) { /* * Try to find a matching device option. */ if (bstrncasecmp(bp, device_options[i].name, device_options[i].compare_size)) { switch (device_options[i].type) { case argument_profile: m_profile = bp + device_options[i].compare_size; done = true; break; case argument_bucket: m_object_bucketname = bp + device_options[i].compare_size; done = true; break; default: break; } } } if (!done) { Mmsg1(errmsg, _("Unable to parse device option: %s\n"), bp); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } bp = next_option; } if (!m_profile) { Mmsg0(errmsg, _("No droplet profile configured\n")); Emsg0(M_FATAL, 0, errmsg); goto bail_out; } /* * Strip any .profile prefix from the libdroplet profile name. */ len = strlen(m_profile); if (len > 8 && bstrcasecmp(m_profile + (len - 8), ".profile")) { m_profile[len - 8] = '\0'; } } /* * See if we need to setup a new context for this device. */ if (!m_ctx) { char *bp; /* * See if this is a path. */ bp = strrchr(m_object_configstring, '/'); if (!bp) { /* * Only a profile name. */ m_ctx = dpl_ctx_new(NULL, m_object_configstring); } else { if (bp == m_object_configstring) { /* * Profile in root of filesystem */ m_ctx = dpl_ctx_new("/", bp + 1); } else { /* * Profile somewhere else. */ *bp++ = '\0'; m_ctx = dpl_ctx_new(m_object_configstring, bp); } } /* * If we failed to allocate a new context fail the open. */ if (!m_ctx) { Mmsg1(errmsg, _("Failed to create a new context using config %s\n"), dev_options); return -1; } /* * Login if that is needed for this backend. */ status = dpl_login(m_ctx); switch (status) { case DPL_SUCCESS: break; case DPL_ENOTSUPP: /* * Backend doesn't support login which is fine. */ break; default: Mmsg2(errmsg, _("Failed to login for voume %s using dpl_login(): ERR=%s.\n"), getVolCatName(), dpl_status_str(status)); return -1; } /* * If a bucketname was defined set it in the context. */ if (m_object_bucketname) { m_ctx->cur_bucket = m_object_bucketname; } } /* * See if we don't have a file open already. */ if (m_vfd) { dpl_close(m_vfd); m_vfd = NULL; } /* * Create some options for libdroplet. * * DPL_OPTION_NOALLOC - we provide the buffer to copy the data into * no need to let the library allocate memory we * need to free after copying the data. */ memset(&dpl_options, 0, sizeof(dpl_options)); dpl_options.mask |= DPL_OPTION_NOALLOC; if (flags & O_CREAT) { dpl_flags = DPL_VFILE_FLAG_CREAT | DPL_VFILE_FLAG_RDWR; status = dpl_open(m_ctx, /* context */ getVolCatName(), /* locator */ dpl_flags, /* flags */ &dpl_options, /* options */ NULL, /* condition */ NULL, /* metadata */ NULL, /* sysmd */ NULL, /* query_params */ NULL, /* stream_status */ &m_vfd); } else { dpl_flags = DPL_VFILE_FLAG_RDWR; status = dpl_open(m_ctx, /* context */ getVolCatName(), /* locator */ dpl_flags, /* flags */ &dpl_options, /* options */ NULL, /* condition */ NULL, /* metadata */ NULL, /* sysmd */ NULL, /* query_params */ NULL, /* stream_status */ &m_vfd); } switch (status) { case DPL_SUCCESS: m_offset = 0; return 0; default: Mmsg2(errmsg, _("Failed to open %s using dpl_open(): ERR=%s.\n"), getVolCatName(), dpl_status_str(status)); m_vfd = NULL; return droplet_errno_to_system_errno(status); } bail_out: return -1; }
int cmd_put(int argc, char **argv) { int ret; char opt; dpl_canned_acl_t canned_acl = DPL_CANNED_ACL_PRIVATE; int Aflag = 0; int i; int fd = -1; dpl_dict_t *metadata = NULL; char *local_file = NULL; char *remote_file = NULL; dpl_vfile_t *vfile = NULL; size_t block_size = 64*1024; ssize_t cc; struct stat st; int kflag = 0; char *buf; var_set("status", "1", VAR_CMD_SET, NULL); optind = 0; while ((opt = getopt(argc, argv, usage_getoptstr(put_usage))) != -1) switch (opt) { case 'k': kflag = 1; break ; case 'm': metadata = dpl_parse_metadata(optarg); if (NULL == metadata) { fprintf(stderr, "error parsing metadata\n"); return SHELL_CONT; } break ; case 'a': canned_acl = dpl_canned_acl(optarg); if (-1 == canned_acl) { fprintf(stderr, "bad canned acl '%s'\n", optarg); return SHELL_CONT; } break ; case 'A': Aflag = 1; break ; case '?': default: usage_help(&put_cmd); return SHELL_CONT; } argc -= optind; argv += optind; if (1 == Aflag) { for (i = 0;i < DPL_N_CANNED_ACL;i++) printf("%s\n", dpl_canned_acl_str(i)); return SHELL_CONT; } if (2 == argc) { char *p, *p2; local_file = argv[0]; remote_file = argv[1]; p = index(remote_file, ':'); if (NULL != p) { p++; if (!strcmp(p, "")) { p2 = rindex(local_file, '/'); if (NULL != p2) { p2++; strcat(remote_file, p2); } else { strcat(remote_file, local_file); } } } } else if (1 == argc) { local_file = argv[0]; remote_file = rindex(local_file, '/'); if (NULL != remote_file) remote_file++; else remote_file = local_file; } else { usage_help(&put_cmd); return SHELL_CONT; } fd = open(local_file, O_RDONLY); if (-1 == fd) { perror("open"); goto end; } buf = alloca(block_size); ret = fstat(fd, &st); if (-1 == ret) { perror("fstat"); return SHELL_CONT; } ret = dpl_openwrite(ctx, remote_file, DPL_VFILE_FLAG_CREAT | (1 == kflag ? DPL_VFILE_FLAG_ENCRYPT : DPL_VFILE_FLAG_MD5), metadata, canned_acl, st.st_size, &vfile); if (DPL_SUCCESS != ret) { fprintf(stderr, "status: %s (%d)\n", dpl_status_str(ret), ret); return SHELL_CONT; } while (1) { cc = read(fd, buf, block_size); if (-1 == cc) { perror("read"); return -1; } if (0 == cc) { break ; } ret = dpl_write(vfile, buf, cc); if (DPL_SUCCESS != ret) { fprintf(stderr, "write failed\n"); return SHELL_CONT; } if (1 == hash) { fprintf(stderr, "#"); fflush(stderr); } } ret = dpl_close(vfile); if (DPL_SUCCESS != ret) { fprintf(stderr, "close failed %s (%d)\n", dpl_status_str(ret), ret); return SHELL_CONT; } vfile = NULL; var_set("status", "0", VAR_CMD_SET, NULL); end: if (-1 != fd) close(fd); if (NULL != metadata) dpl_dict_free(metadata); if (NULL != vfile) dpl_close(vfile); return SHELL_CONT; }