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;
   }
}
Beispiel #2
0
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;
}
Beispiel #5
0
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;
}