Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 6bc542b in mainline


Ignore:
Timestamp:
2015-07-02T21:53:12Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
99c23405
Parents:
6a0d4ce2
Message:

Allocate and create partition with libfdisk (except actual modification of on-disk label).

Location:
uspace
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/vbd.c

    r6a0d4ce2 r6bc542b  
    107107}
    108108
    109 #include <io/log.h>
    110109/** Get disk information. */
    111110int vbd_disk_info(vbd_t *vbd, service_id_t sid, vbd_disk_info_t *vinfo)
     
    115114        ipc_call_t answer;
    116115
    117         log_msg(LOG_DEFAULT, LVL_DEBUG, "vbd_disk_info() begin exchange");
    118116        exch = async_exchange_begin(vbd->sess);
    119117        aid_t req = async_send_1(exch, VBD_DISK_INFO, sid, &answer);
    120         log_msg(LOG_DEFAULT, LVL_DEBUG, "vbd_disk_info() read start");
    121118        int rc = async_data_read_start(exch, vinfo, sizeof(vbd_disk_info_t));
    122         log_msg(LOG_DEFAULT, LVL_DEBUG, "vbd_disk_info() end exch");
    123119        async_exchange_end(exch);
    124120
     
    128124        }
    129125
    130         log_msg(LOG_DEFAULT, LVL_DEBUG, "vbd_disk_info() wait fore req reply");
    131126        async_wait_for(req, &retval);
    132127        if (retval != EOK)
    133128                return EIO;
    134129
    135         log_msg(LOG_DEFAULT, LVL_DEBUG, "vbd_disk_info() done");
    136130        return EOK;
    137131}
     
    293287{
    294288        async_exch_t *exch;
    295         sysarg_t part;
     289        sysarg_t retval;
     290        ipc_call_t answer;
     291
     292        exch = async_exchange_begin(vbd->sess);
     293        aid_t req = async_send_1(exch, VBD_PART_CREATE, disk, &answer);
     294        int rc = async_data_write_start(exch, pspec, sizeof(vbd_part_spec_t));
     295        async_exchange_end(exch);
     296
     297        if (rc != EOK) {
     298                async_forget(req);
     299                return EIO;
     300        }
     301
     302        async_wait_for(req, &retval);
     303        if (retval != EOK)
     304                return EIO;
     305
     306        *rpart = (vbd_part_id_t)IPC_GET_ARG1(answer);
     307        return EOK;
     308
     309}
     310
     311int vbd_part_delete(vbd_t *vbd, vbd_part_id_t part)
     312{
     313        async_exch_t *exch;
    296314        int retval;
    297315
    298316        exch = async_exchange_begin(vbd->sess);
    299         retval = async_req_1_1(exch, VBD_PART_CREATE, disk, &part);
    300         async_exchange_end(exch);
    301 
    302         if (retval != EOK)
    303                 return EIO;
    304 
    305         *rpart = (vbd_part_id_t)part;
    306         return EOK;
    307 }
    308 
    309 int vbd_part_delete(vbd_t *vbd, vbd_part_id_t part)
    310 {
    311         async_exch_t *exch;
    312         int retval;
    313 
    314         exch = async_exchange_begin(vbd->sess);
    315317        retval = async_req_1_0(exch, VBD_PART_DELETE, part);
    316318        async_exchange_end(exch);
  • uspace/lib/c/include/vbd.h

    r6a0d4ce2 r6bc542b  
    5959} vbd_disk_info_t;
    6060
     61/** Specification of new partition */
    6162typedef struct {
     63        /** Partition index */
     64        int index;
     65        /** First block */
     66        aoff64_t block0;
     67        /** Number of blocks */
     68        aoff64_t nblocks;
     69        /** Partition type */
     70        uint64_t ptype;
    6271} vbd_part_spec_t;
    6372
     73/** Partition info */
    6474typedef struct {
    6575        /** Partition index */
  • uspace/lib/fdisk/src/fdisk.c

    r6a0d4ce2 r6bc542b  
    5858};
    5959
     60static int fdisk_part_spec_prepare(fdisk_dev_t *, fdisk_part_spec_t *,
     61    vbd_part_spec_t *);
     62
    6063static void fdisk_dev_info_delete(fdisk_dev_info_t *info)
    6164{
     
    497500        int rc;
    498501
    499         part = calloc(1, sizeof(fdisk_part_t));
    500         if (part == NULL)
    501                 return ENOMEM;
    502 
     502        printf("fdisk_part_create()\n");
     503
     504        rc = fdisk_part_spec_prepare(dev, pspec, &vpspec);
     505        if (rc != EOK)
     506                return EIO;
     507
     508        printf("fdisk_part_create() - call vbd_part_create\n");
    503509        rc = vbd_part_create(dev->fdisk->vbd, dev->sid, &vpspec, &partid);
    504         if (rc != EOK) {
    505                 free(part);
    506                 return EIO;
    507         }
    508 
    509         rc = fdisk_part_add(dev, partid, rpart);
     510        if (rc != EOK)
     511                return EIO;
     512
     513        printf("fdisk_part_create() - call fdisk_part_add\n");
     514        rc = fdisk_part_add(dev, partid, &part);
    510515        if (rc != EOK) {
    511516                /* Try rolling back */
     
    514519        }
    515520
    516         (*rpart)->fstype = pspec->fstype;
    517         (*rpart)->capacity = pspec->capacity;
    518 
     521        printf("fdisk_part_create() - done\n");
     522        part->fstype = pspec->fstype;
     523        part->capacity = pspec->capacity;
     524
     525        if (rpart != NULL)
     526                *rpart = part;
    519527        return EOK;
    520528}
     
    650658}
    651659
     660/** Get free partition index. */
     661static int fdisk_part_get_free_idx(fdisk_dev_t *dev, int *rindex)
     662{
     663        link_t *link;
     664        fdisk_part_t *part;
     665        int nidx;
     666
     667        link = list_first(&dev->parts_idx);
     668        nidx = 1;
     669        while (link != NULL) {
     670                part = list_get_instance(link, fdisk_part_t, ldev_idx);
     671                if (part->index > nidx)
     672                        break;
     673                nidx = part->index;
     674                link = list_next(link, &dev->parts_idx);
     675        }
     676
     677        if (nidx > 4 /* XXXX actual number of slots*/) {
     678                return ELIMIT;
     679        }
     680
     681        *rindex = nidx;
     682        return EOK;
     683}
     684
     685/** Get free range of blocks.
     686 *
     687 * Get free range of blocks of at least the specified size (first fit).
     688 */
     689static int fdisk_part_get_free_range(fdisk_dev_t *dev, aoff64_t nblocks,
     690    aoff64_t *rblock0, aoff64_t *rnblocks)
     691{
     692        link_t *link;
     693        fdisk_part_t *part;
     694        uint64_t avail;
     695        int nba;
     696
     697        link = list_first(&dev->parts_ba);
     698        nba = dev->dinfo.ablock0;
     699        while (link != NULL) {
     700                part = list_get_instance(link, fdisk_part_t, ldev_ba);
     701                if (part->block0 - nba >= nblocks)
     702                        break;
     703                nba = part->block0 + part->nblocks;
     704                link = list_next(link, &dev->parts_ba);
     705        }
     706
     707        if (link != NULL) {
     708                /* Free range before a partition */
     709                avail = part->block0 - nba;
     710        } else {
     711                /* Free range at the end */
     712                avail = dev->dinfo.ablock0 + dev->dinfo.anblocks - nba;
     713
     714                /* Verify that the range is large enough */
     715                if (avail < nblocks)
     716                        return ELIMIT;
     717        }
     718
     719        *rblock0 = nba;
     720        *rnblocks = avail;
     721        return EOK;
     722}
     723
     724/** Prepare new partition specification for VBD. */
     725static int fdisk_part_spec_prepare(fdisk_dev_t *dev, fdisk_part_spec_t *pspec,
     726    vbd_part_spec_t *vpspec)
     727{
     728        uint64_t cbytes;
     729        aoff64_t req_blocks;
     730        aoff64_t fblock0;
     731        aoff64_t fnblocks;
     732        uint64_t block_size;
     733        unsigned i;
     734        int index;
     735        int rc;
     736
     737//      pspec->fstype
     738        printf("fdisk_part_spec_prepare()\n");
     739        block_size = dev->dinfo.block_size;
     740        cbytes = pspec->capacity.value;
     741        for (i = 0; i < pspec->capacity.cunit; i++)
     742                cbytes = cbytes * 1000;
     743
     744        req_blocks = (cbytes + block_size - 1) / block_size;
     745
     746        rc = fdisk_part_get_free_idx(dev, &index);
     747        if (rc != EOK)
     748                return EIO;
     749
     750        rc = fdisk_part_get_free_range(dev, req_blocks, &fblock0, &fnblocks);
     751        if (rc != EOK)
     752                return EIO;
     753
     754        vpspec->index = index;
     755        vpspec->block0 = fblock0;
     756        vpspec->nblocks = req_blocks;
     757        vpspec->ptype = 42;
     758        return EOK;
     759}
     760
    652761/** @}
    653762 */
  • uspace/lib/label/include/types/liblabel.h

    r6a0d4ce2 r6bc542b  
    9898/** Specification of new partition */
    9999struct label_part_spec {
     100        /** Partition index */
     101        int index;
     102        /** First block */
     103        aoff64_t block0;
     104        /** Number of blocks */
     105        aoff64_t nblocks;
     106        /** Partition type */
     107        uint64_t ptype;
    100108};
    101109
  • uspace/lib/label/src/gpt.c

    r6a0d4ce2 r6bc542b  
    242242    label_part_t **rpart)
    243243{
    244         return ENOTSUP;
     244        label_part_t *part;
     245
     246        part = calloc(1, sizeof(label_part_t));
     247        if (part == NULL)
     248                return ENOMEM;
     249
     250        /* XXX Verify index, block0, nblocks */
     251
     252        part->index = pspec->index;
     253        part->block0 = pspec->block0;
     254        part->nblocks = pspec->nblocks;
     255
     256        /* XXX Modify partition table */
     257
     258        part->label = label;
     259        list_append(&part->llabel, &label->parts);
     260
     261        *rpart = part;
     262        return EOK;
    245263}
    246264
  • uspace/lib/label/src/mbr.c

    r6a0d4ce2 r6bc542b  
    206206    label_part_t **rpart)
    207207{
    208         return ENOTSUP;
     208        label_part_t *part;
     209
     210        part = calloc(1, sizeof(label_part_t));
     211        if (part == NULL)
     212                return ENOMEM;
     213
     214        part->index = pspec->index;
     215        part->block0 = pspec->block0;
     216        part->nblocks = pspec->nblocks;
     217
     218        part->label = label;
     219
     220        *rpart = part;
     221        return EOK;
    209222}
    210223
  • uspace/srv/bd/vbd/disk.c

    r6a0d4ce2 r6bc542b  
    112112}
    113113
    114 static int vbds_part_add(vbds_disk_t *disk, label_part_t *lpart)
     114static int vbds_part_add(vbds_disk_t *disk, label_part_t *lpart,
     115    vbds_part_t **rpart)
    115116{
    116117        vbds_part_t *part;
     
    163164        list_append(&part->lparts, &vbds_parts);
    164165
     166        if (rpart != NULL)
     167                *rpart = part;
    165168        return EOK;
    166169}
     
    230233        part = label_part_first(label);
    231234        while (part != NULL) {
    232                 rc = vbds_part_add(disk, part);
     235                rc = vbds_part_add(disk, part, NULL);
    233236                if (rc != EOK) {
    234237                        log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding partitio "
     
    389392}
    390393
    391 int vbds_part_create(service_id_t sid, vbds_part_id_t *rpart)
     394int vbds_part_create(service_id_t sid, vbd_part_spec_t *pspec,
     395    vbds_part_id_t *rpart)
    392396{
    393397        vbds_disk_t *disk;
    394398        vbds_part_t *part;
    395         label_part_spec_t pspec;
     399        label_part_spec_t lpspec;
    396400        label_part_t *lpart;
    397401        int rc;
    398 
    399         part = calloc(1, sizeof(vbds_part_t));
    400         if (part == NULL)
    401                 return ENOMEM;
    402402
    403403        rc = vbds_disk_by_svcid(sid, &disk);
     
    408408        }
    409409
    410         label_pspec_init(&pspec);
    411         rc = label_part_create(disk->label, &pspec, &lpart);
     410        label_pspec_init(&lpspec);
     411        lpspec.index = pspec->index;
     412        lpspec.block0 = pspec->block0;
     413        lpspec.nblocks = pspec->nblocks;
     414        lpspec.ptype = pspec->ptype;
     415
     416        rc = label_part_create(disk->label, &lpspec, &lpart);
    412417        if (rc != EOK) {
    413418                log_msg(LOG_DEFAULT, LVL_ERROR, "Error creating partition.");
     
    415420        }
    416421
    417         rc = vbds_part_add(disk, lpart);
     422        rc = vbds_part_add(disk, lpart, &part);
    418423        if (rc != EOK) {
    419424                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed while creating "
     
    427432        }
    428433
     434        if (rpart != NULL)
     435                *rpart = part->id;
    429436        return EOK;
    430437error:
    431         free(part);
    432438        return rc;
    433439}
  • uspace/srv/bd/vbd/disk.h

    r6a0d4ce2 r6bc542b  
    5050extern int vbds_label_delete(service_id_t);
    5151extern int vbds_part_get_info(vbds_part_id_t, vbd_part_info_t *);
    52 extern int vbds_part_create(service_id_t, vbds_part_id_t *);
     52extern int vbds_part_create(service_id_t, vbd_part_spec_t *,vbds_part_id_t *);
    5353extern int vbds_part_delete(vbds_part_id_t);
    5454extern void vbds_bd_conn(ipc_callid_t, ipc_call_t *, void *);
  • uspace/srv/bd/vbd/vbd.c

    r6a0d4ce2 r6bc542b  
    115115        rc = vbds_disk_info(disk_sid, &dinfo);
    116116        if (rc != EOK) {
    117                 log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() call failed");
    118                 async_answer_0(iid, rc);
    119                 return;
    120         }
    121 
    122         log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() data_read_receive");
     117                async_answer_0(iid, rc);
     118                return;
     119        }
     120
    123121        ipc_callid_t callid;
    124122        size_t size;
    125123        if (!async_data_read_receive(&callid, &size)) {
    126                 log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() failed");
    127124                async_answer_0(callid, EREFUSED);
    128125                async_answer_0(iid, EREFUSED);
     
    130127        }
    131128
    132         log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() check size");
    133129        if (size != sizeof(vbds_disk_info_t)) {
    134                 log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() wrong size");
    135130                async_answer_0(callid, EINVAL);
    136131                async_answer_0(iid, EINVAL);
     
    138133        }
    139134
    140         log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() data_read_finalize");
    141135        rc = async_data_read_finalize(callid, &dinfo,
    142136            min(size, sizeof(dinfo)));
     
    147141        }
    148142
    149         log_msg(LOG_DEFAULT, LVL_NOTE, "vbd_disk_info() reply EOK");
    150143        async_answer_0(iid, EOK);
    151144}
     
    234227{
    235228        service_id_t disk_sid;
     229        vbd_part_spec_t pspec;
    236230        vbds_part_id_t part;
    237231        int rc;
     
    240234
    241235        disk_sid = IPC_GET_ARG1(*icall);
    242         rc = vbds_part_create(disk_sid, &part);
     236
     237        ipc_callid_t callid;
     238        size_t size;
     239        if (!async_data_write_receive(&callid, &size)) {
     240                async_answer_0(callid, EREFUSED);
     241                async_answer_0(iid, EREFUSED);
     242                return;
     243        }
     244
     245        if (size != sizeof(vbd_part_spec_t)) {
     246                async_answer_0(callid, EINVAL);
     247                async_answer_0(iid, EINVAL);
     248                return;
     249        }
     250
     251        rc = async_data_write_finalize(callid, &pspec, sizeof(vbd_part_spec_t));
     252        if (rc != EOK) {
     253                async_answer_0(callid, rc);
     254                async_answer_0(iid, rc);
     255                return;
     256        }
     257
     258        rc = vbds_part_create(disk_sid, &pspec, &part);
     259        if (rc != EOK) {
     260                async_answer_0(iid, rc);
     261                return;
     262        }
     263
    243264        async_answer_1(iid, (sysarg_t)rc, (sysarg_t)part);
    244265}
Note: See TracChangeset for help on using the changeset viewer.